Archive

Archive for the ‘RIA Services’ Category

Using asp.net Membership and profile providers with RIA Services

March 25, 2009 lee Leave a comment

After reading about RIA services. I wanted to write some sample code to hook into asp.net Membership and profile providers.

So I wrote couple of custom providers.

MembershipProvider

I had a simple table with UserID,UserName,Email and password columns
I did not bother with all the different overloads. I have just added code in few places like Initialize, GetUser, ValidateUser and CreateUser

ProfileProvider

I created a table which will store 3 values for each user, Theme, City and State

again I did not code for all the different overloads. I have added code for Initialize, SetPropertyValues, GetPropertyValues

once I had these providers in place

I added a Silverlight application with Webproject

and modified the Web.config file to add my providers

 <membership defaultProvider=”SampleMembershipProvider1″ >
      <providers>
        <clear/>
        <add name=”SampleMembershipProvider1″ type=”CustomProviders.SampleMembershipProvider” connectionStringName=”constring” enablePasswordRetrieval=”true” enablePasswordReset=”true” requiresQuestionAndAnswer=”true” writeExceptionsToEventLog=”false”/>
      </providers>
    </membership>

    <profile defaultProvider=”SampleProfileProvider1″>
      <providers>
        <add name=”SampleProfileProvider1″ type=”CustomProviders.SampleProfileProvider” connectionStringName=”constring” />
      </providers>
      <properties>
        <add name=”Theme” type=”System.Int32″ allowAnonymous=”true”/>
        <add name=”City” type=”System.String” allowAnonymous=”true”/>
        <add name=”State” type=”System.String” allowAnonymous=”true”/>
      </properties>
    </profile>

The next step is to add a new DomainService to the webproject
Adding the following code will get us started

[EnableClientAccess]
    public class Authentication : AuthenticationBase<UserBase> { }

as we have a profile also,created another class User inheriting from UserBase

 [EnableClientAccess]
    public class Authentication : AuthenticationBase<User> { }
    public class User : UserBase
    {
        public int Theme { get; set; }
        public string City { get; set; }
        public string State { get; set; }
    }

I added the following class so that we can have a Page(UI) in Silverlight which allows for user Registration

    [EnableClientAccess]
    public class MembershipService : DomainService
    {
        [ServiceOperation]
        public void AddUser(string userName, string password, string email)
        {
            MembershipCreateStatus createStatus;

            Membership.CreateUser(userName, password, email, null, null, true, out createStatus);
            if (createStatus != MembershipCreateStatus.Success)
            {
                throw new DomainServiceException(createStatus.ToString());
            }
        }
    }

We also need to add a Service to App.XAML
 <Application.Services>
        <appsvc:WebUserService x:Name=”UserService” />
    </Application.Services>
The sample does not have any UI, but when the page is loaded it will create a user and login the user as you can see from the code below

 public partial class MainPage : UserControl
    {
        UserService service;
        public MainPage()
        {
            InitializeComponent();
            CreateUser();                             
        }

        void CreateUser()
        {
            MembershipContext ctx = new MembershipContext();
            ctx.AddUserCompleted += new EventHandler<System.Windows.Ria.Data.InvokeEventArgs>(ctx_AddUserCompleted);
            ctx.AddUser(“user1″, “test”, “user@test.com“);
        }
        void ctx_AddUserCompleted(object sender, System.Windows.Ria.Data.InvokeEventArgs e)
        {
            MessageBox.Show(“User added”);
            Login();
        }

        void Login()
        {
            service = App.Current.Services["UserService"] as UserService;
            service.LoginCompleted += new EventHandler<LoginCompletedEventArgs>(service_LoginCompleted);
            service.Login(“user1″, “test”);
        }
        void service_LoginCompleted(object sender, LoginCompletedEventArgs e)
        {
            User user = (service.User as User);
            if (string.IsNullOrEmpty(user.City))
            {
                user.City = “dallas”;
                user.State = “TX”;
                user.Theme = 100;
                service.SaveUserCompleted += new EventHandler<SaveUserCompletedEventArgs>(service_SaveUserCompleted);
                service.SaveUser();

            }           
        }

        void service_SaveUserCompleted(object sender, SaveUserCompletedEventArgs e)
        {
            MessageBox.Show(“login success and profile properies set”);
        }
    }

you can download the code here

RIA Services – sample

March 20, 2009 lee Leave a comment

This sample doesnt do a whole lot but, I had to post in the forums twice to even get this working. so I thought it might be helpful to point out some of the issues I faced and how to solve similar problems. All it does is display list of customers and when you click on details, it shows details of the customer and his orders in a childwindow

The following is the reply clarfying the scenario from David
To be clear regarding EF and DomainDataSource, this is not a general issue — it should only present itself when a LoadSize is set because EF doesn’t support Skip() and Take() on unordered data. This would be the case even if you were using the underlying DomainContext to perform the same operations.

Ultimately, it’s an EF limitation. As long as the queries on your DomainService support Skip and Take, you can expect the DomainDataSource to work just fine (with LoadSize and PageSize) with them. Similarly, if your DomainService queries don’t support OrderBy(), ThenBy() or Where(), you shouldn’t expect sorting, grouping, or filtering to work using the DomainDataSource. Nonetheless, we’re looking at some ways to make it less likely that people will encounter this issue.In regards to your other issue with the DataPager, there may be a bug here that we will look into. My hunch is that it’s a timing issue, which is why setting the PageSize on the DDS fixes the problem.”

ria41
ria42
1. if we are using EntityFramework then the DomainDataSource  might not work correctly. you have to specify SortDescriptors(in bold)

  <riaControls:DomainDataSource x:Name=”source” LoadSize=”30″   LoadMethodName=”LoadCustomers” >
            <riaControls:DomainDataSource.DomainContext>
                <ds:NorthwindContext/>
            </riaControls:DomainDataSource.DomainContext>
            <riaControls:DomainDataSource.SortDescriptors>
                <riaData:SortDescriptor PropertyPath=”CustomerID” Direction=”Ascending” />
            </riaControls:DomainDataSource.SortDescriptors>
        </riaControls:DomainDataSource>

2. I Had a situation where I am calling a parameterized constructor

Details details = new Details((sender as Button).DataContext as Customers);
            details.Show();

and in the details page

public Details(Customers c)
        {
            InitializeComponent();          
            dataForm1.CurrentItem = c;
Parameter p = new Parameter();
            p.ParameterName = “customerId”;
            p.Value = c.CustomerID;
            source.LoadParameters.Add(p);
            source.Load();
        }

The above code is throwing exceptions when PageSize is specified on the DataPager, to get around that we need to specify on the DomainDataSource

you can download the code here (it is a bit big as database is also included in it)

Silverlight 3 – RIA Services

March 19, 2009 lee Leave a comment

I started playing with the beta bits of the RIA Services and started to create a simple app, where list of customers will be displayed in a DataGrid  and a page size of 10 and will be edited using DataForm.

This is the XAML I had

<UserControl xmlns:dataControls=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm”  xmlns:data=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data”  x:Class=”SilverlightApplication10.MainPage”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml
             xmlns:riaControls=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls”
             xmlns:riaData=”clr-namespace:System.Windows.Data;assembly=System.Windows.Ria.Controls”
             xmlns:domain=”clr-namespace:SilverlightApplication10.Web”
    Width=”800″ Height=”600″>
    <Grid Margin=”10″ x:Name=”LayoutRoot” Background=”White”>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <riaControls:DomainDataSource x:Name=”source” LoadSize=”100″   LoadMethodName=”LoadCustomers” AutoLoad=”True”>
            <riaControls:DomainDataSource.DomainContext>
                <domain:NorthwindContext />
            </riaControls:DomainDataSource.DomainContext>
        </riaControls:DomainDataSource>
        <StackPanel>
             <dataControls:DataPager PageSize=”10″   Source=”{Binding Data, ElementName=source}” />
        <data:DataGrid x:Name=”datagrid1″ ItemsSource=”{Binding Data, ElementName=source}” IsReadOnly=”True” AutoGenerateColumns=”False” >
            <data:DataGrid.Columns>
                <data:DataGridTextColumn Header=”Customer ID” Binding=”{Binding CustomerID}”/>
                <data:DataGridTextColumn  Header=”Contact Name” Binding=”{Binding ContactName}”/>
                <data:DataGridTextColumn  Header=”Contact Title” Binding=”{Binding ContactTitle}”/>
            </data:DataGrid.Columns>
        </data:DataGrid>
        </StackPanel>       
            <!–<dataControls:DataForm WrapAfter=”4″ AutoEdit=”True”     Header=”Customer Details”  CurrentItem=”{Binding ElementName=datagrid1, Path=SelectedItem}” Grid.Row=”1″></dataControls:DataForm>–>
      
    </Grid>
</UserControl>

ria1

everything  looks good,  clicked the button in the pager to go to the lastpage, there are only 91 records, so not sure if the pager is displaying loadsize/pagesize as number of pages, but I get this. cannot go to the first page. looks like it knows there are is no data in Page 10, and but the UI is not reflecting that.  if we click the next button in the pager we go to 2nd page

ria2

When the loadsize is specified to something less than 91 (say 30), I can see data for 3 pages but when I navigate to 4th page, I dont  get data

I uncommented the DataForm and ran the sample

ria3

I noticed the following

1. Pager functionality not there

2. AutoEdit  on the DataForm is set to true, so it goes into edit mode and displays Save and Cancel buttons. Cancel is grayed out and it shows there are some pending changes. if we select another Item in the datagrid everything is good.

3. If I remove the AutoEdit  on DataForm  pager seems to work, but when I go to next page, Datagrid doesnt select the first item by default so the DataForm is empty