Deborah's Developer MindScape






         Tips and Techniques for Web and .NET developers.

November 25, 2009

Silverlight and RIA Services: Managing Your Codes

Filed under: ASP.NET RIA Services,C#,Silverlight,VB.NET @ 1:15 pm

Every application has some type of codes: customer types, reason codes, states, and so on. Sometimes these codes can be hard-coded in an application as Enum values. But other times these codes are more readily stored in a table. This post details how to work with code tables through RIA Services.

[For details on how to work with Enum values through RIA Services, see this prior post.]

NOTE: This example continues from this prior post that introduces RIA Services and your business objects.

Building the Business Layer Classes

To manage the codes in your application without having to build a class for each type of code, you can build a more generalized Code class in your business layer. This class is added to the project containing the Customer and Customers classes from this prior post.

In C#:

using System.ComponentModel.DataAnnotations;

namespace BoCSharp
{
    public class Code
    {
        [Key()]
        public int CodeId { get; set; }
        public string CodeText { get; set; }
    }
}

In VB:

Imports System.ComponentModel.DataAnnotations

Public Class Code

    Private _CodeId As Integer
    <Key()> _
    Public Property CodeId() As Integer
        Get
            Return _CodeId
        End Get
        Set(ByVal value As Integer)
            _CodeId = value
        End Set
    End Property

    Private _CodeText As String
    Public Property CodeText() As String
        Get
            Return _CodeText
        End Get
        Set(ByVal value As String)
            _CodeText = value
        End Set
    End Property
End Class

Each code has an Id and a text value. The Key() attribute on the CodeId ensures that this class is set up to use RIA Services.

A separate class in the business layer then tracks the sets of all codes.

In C#:

using System.Collections.Generic;

namespace BoCSharp
{
    public class Codes
    {
        public static List<Code> RetrieveCustomerTypes()
        {
            List<Code> custTypeList = new List<Code>
                {new Code()
                    {CodeId=1,
                     CodeText="Individual"},
                new Code()
                    {CodeId=2,
                     CodeText="Corporate"},
                new Code()
                    {CodeId=3,
                     CodeText="Government"},
                new Code()
                    {CodeId=4,
                     CodeText="Education"}};
            return custTypeList;
        }
    }
}

In VB:

Public Class Codes

    Public Shared Function RetrieveCustomerTypes() As List(Of Code)
        Dim custTypeList As New List(Of Code)
        custTypeList.Add(New Code With { _
                         .CodeId = 1, _
                         .CodeText = "Individual"})
        custTypeList.Add(New Code With { _
                         .CodeId = 2, _
                         .CodeText = "Corporate"})
        custTypeList.Add(New Code With { _
                         .CodeId = 3, _
                         .CodeText = "Government"})
        custTypeList.Add(New Code With { _
                         .CodeId = 4, _
                         .CodeText = "Education"})
        Return custTypeList
    End Function
End Class

Two things to note about this class:

  1. It will have a Retrieve method for each kind of code (customer types, reason codes, states, and so on).
  2. In the "real" application, it will get these values from the database instead of hard-coded values. (Hard-coded values are used here so you don’t have to set up a database to try these techniques.)

Finally, let’s modify the Customer class to add the customer type property. Each customer has a customer type.

In C#:

using System.ComponentModel.DataAnnotations;
namespace BoCSharp
{
    public class Customer
    {
        [Key()]
        public int CustomerId { get; set; }
        public int CustomerTypeId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string EmailAddress { get; set; }

        public Customer()
        {
        }
     }
}

In VB:

Imports System.ComponentModel.DataAnnotations
Public Class Customer

    Private _CustomerId As Integer
    <Key()> _
    Public Property CustomerId() As Integer
        Get
            Return _CustomerId
        End Get
        Set(ByVal value As Integer)
            _CustomerId = value
        End Set
    End Property

    Private _CustomerTypeId As Integer
    Public Property CustomerTypeId() As Integer
        Get
            Return _CustomerTypeId
        End Get
        Set(ByVal value As Integer)
            _CustomerTypeId = value
        End Set
    End Property

    Private _FirstName As String
    Public Property FirstName() As String
        Get
            Return _FirstName
        End Get
        Set(ByVal value As String)
            _FirstName = value
        End Set
    End Property

    Private _LastName As String
    Public Property LastName() As String
        Get
            Return _LastName
        End Get
        Set(ByVal value As String)
            _LastName = value
        End Set
    End Property

    Private _EmailAddress As String
    Public Property EmailAddress() As String
        Get
            Return _EmailAddress
        End Get
        Set(ByVal value As String)
            _EmailAddress = value
        End Set
    End Property
End Class

Though only the CustomerTypeId is new, all of the code from the Customer class (originally defined in this prior post) is shown above.

Building the Domain Service Class

The next step is to build a Domain Service class for the Codes class so that the Silverlight project can access the codes.

In C#:

namespace SLCSharp.Web
{
    using BoCSharp;
    using System.Collections.Generic;
    using System.Web.Ria;
    using System.Web.DomainServices; 

    [EnableClientAccess()]
    public class CodeService : DomainService
    {
        public IEnumerable<Code> GetCustomerTypes()
        {
            return Codes.RetrieveCustomerTypes();
        }
    }
}

In VB:

Imports System.Web.DomainServices
Imports System.Web.Ria

<EnableClientAccess()> _
Public Class CodeService
    Inherits DomainService

    Public Function GetCustomerTypes() As IEnumerable(Of Code)
        Return Codes.RetrieveCustomerTypes()
    End Function
End Class

This class will have a function to expose each type of code. For now, it provides a function to get the customer types.

Accessing the Codes from Silverlight

One of the common ways to use the codes in Silverlight is to present them in a ComboBox. This involves two steps:

  1. Add a DomainDataSource that accesses the Domain Service class.
  2. Add a ComboBox that binds to the DomainDataSource.

In XAML:

<UserControl x:Class="SLVB.CodesExampleUC"
    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:domain="clr-namespace:SLVB.Web"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <riaControls:DomainDataSource x:Name="CustomerTypeSource"
                    QueryName="GetCustomerTypes" AutoLoad="True">
            <riaControls:DomainDataSource.DomainContext>
                <domain:CodeContext/>
            </riaControls:DomainDataSource.DomainContext>
        </riaControls:DomainDataSource>
        <StackPanel Margin="10">
            <ComboBox ItemsSource=
                 "{Binding Data, ElementName=CustomerTypeSource}"
                 DisplayMemberPath="CodeText"/>
        </StackPanel>
    </Grid>
</UserControl>

Using the DomainDataSource requires adding two namespaces to the UserControl:

1) xmlns:riaControls is needed for the RIA DomainDataSource control.

NOTE: You won’t find the DomainDataSource control in the toolbox. You need to type it into the XAML manually.

2) xmlns:domain is the namespace for your Web project that launches your Silverlight application.

Define a name for the DomainDataSource using the x:Name property. This is the name used in the binding. Also set the QueryName property to the name of the Domain Service class method that gets the data for this data source. In this case, it is the GetCustomerTypes method.

The DomainDataSource also requires a DomainContext. This is where you define the name of the data context used by the data source. If you don’t see an appropriate context using intellisense, try rebuilding your application. Otherwise you can type in the name. It will be the same name as your Domain Service class but replacing "Service" with "Context". Since this example Domain Service class is CodeService, the context is CodeContext.

The next set of XAML builds a ComboBox inside a StackPanel. The ItemsSource property of the ComboBox defines the binding to the name of the DomainDataSource. The DisplayMemberPath property is set to the name of the class property to display in the ComboBox. In this case, the ComboBox displays the CodeText property.

The result is as follows:

image

Use this technique to access your code tables from your Silverlight application.

Enjoy!

RSS feed for comments on this post. TrackBack URI

Leave a comment

© 2019 Deborah's Developer MindScape   Provided by WPMU DEV -The WordPress Experts   Hosted by Microsoft MVPs