![]() |
Web Development »
Silverlight »
Applications
Intermediate
License: The Code Project Open License (CPOL)
Skeleton for a Silverlight business application based on Ria Services and the Ria Services Class LibraryBy Max PaulouskyThis article presents the techniques and caveats of building Silverlight business applications. It describes breaking down applications into tiers, implementing a data access in N-tier applications, implementing a custom authentication, adding a support of https to Ria Services applications. |
C#3.0, Windows, .NET3.5, ASP.NET, IIS, XAML, LINQ, Silverlight, SQL2005, VS2008, Architect, Dev
|
||||||||||||
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
Real business applications are completely different from samples that can be found in the Internet. The real applications have many layers because all architects are going to divide an application into them to decrease complexity and improve readability of the source code.
Any Silverlight application is a client application. It means the compiled code of such an application runs on the client tier and it has to have access to data that hosted on the server (middle) tier.
There are many ways to get data from the client tier:
Last one was developed specially for rich internet applications (Ria) and provides methods and framework to link client and middle tiers.
.Net Ria Services library adds new kind of Visual Studio project templates "Ria Services Class Library" which allows to create N-tier class libraries.
Also, .Net Ria Services has build-in abilities to use secure connection to protect important data like logins, passwords etc.
Building an application on the Ria Services basis has some tricks, that are not described, because mentioned technology is pretty new and it is available as Preview version (Jul 2009). So, I am going to unlock secrets of building real business applications based on .Net Ria services and Ria services Class Library.
In my opinion, any silverlight business application must have following features:
.Net Ria Services and .Net Ria Services Class Library allow to implement all features above. Demo application has all mentioned features and can be use as a skeleton for all other silverlight business applications.
Following software was used:
This article is concentrated on the back-end rather than the front-end part of the Silverlight applications. So, we can start developing the application based on Business Application project template. This template contains several predefined views, Login and passwords controls. Also, this template contains a couple of services (Authentication, Registration) that can be called from the client tier via Ria services mechanism.
Note: Business Application project template is available if you have installed .Net Ria Services framework (see below for details).
Eventually, "Business Application project" template provides some source code that can be used in the real business application. But it is not enough for real application.
First of all, I have to add a new type of the project to the solution - .NET RIA Services Class Library. This approach allows to build the bridge between client tier (silverlight application) and middle tier.
After that, I have to move Services from web application to RIA Services Class Library. The services will be available for client tier as they are available now.
Then I have to add an entity data model (model of the database) to get access to data. An Authentication and a traffic encryption between the client tier and the middle tier will be supported also.
As a result, my application should consist of four projects:
BASample.Web. This project is a web application and it hosts silverlight application. BASample.Data. This project implements access to the data tier and contains all services that are used by silverlight application. BASample.Silverlight. This project contains all controls and windows that will be displayed for a user. BASample.Data.Silverlight. This project allows to get access to middle tier to the silverlight application. Usually, I change root namespace, assembly name, name of project for each created project (via Project properties window). I'm going to use BASample.Silverlight as a namespace, name of project and name of assembly.
To change namespaces of the Silverlight application, I should change namespaces both in *.cs files ('namespace' and 'using' areas) and in *.xaml files. Attributes of root element of *.xaml file contain namespaces to change:
x:Class="<Namespace>.<className>" xmlns:app="clr-namespace:<Namespace>" Sample of the root element of *.xaml file (The namespace to change is highlighted and underlined):
<controls:ChildWindow
x:Class="BusinessApplication1.LoginWindow"
x:Name="childWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
xmlns:dataform="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit"
xmlns:activity="clr-namespace:System.Windows.Controls;assembly=ActivityControl"
xmlns:app="clr-namespace:BusinessApplication1.Silverlight"
Width="400"
Title="Login"
Style="{StaticResource LogRegWindowStyle}">
I change the namespace of services and other *.cs files (I use BASample.Web) for web application.
I should update .Net Ria services link in the Silverlight application after renaming web project.
Fig. 1. How to update Ria services link after renaming web application.

Also, after updating Ria services link I delete auto-generated file BusinessApplication1.Web.g.cs from Silverlight project (Generated_Code folder) and rebuild the solution - auto-generated file will be recreated with the different name BASample.Web.g.cs. Successful build means that all changes were done correctly.
I've installed Ria Services framework (you can find it here) and I see two additional project templates in the list of Silverlight templates.
Fig. 2. List of Ria Services Silverlight project templates.

I select '.NET RIA Services Class Library', enter name for the project BASample.Data and click 'Ok' to add it to the solution. It will create a solution folder BASample.Data and add two additional projects into there.
Then I update names of assemblies, root namespaces and names of projects for middle and client tiers of RIA Services Class Library (see fig. 3, 4 for details)
Fig. 3. Properties of the middle tier of added .NET RIA Services Class Library.

Fig. 4. Properties of the client tier of added .NET RIA Services Class Library.

I specify correct .Net Ria Services link for client tier library. A correct value is the name of the middle tier of the RIA Services Class Library (BASample.Data) because it will contain data entity model.
After these changes the solution can be built successfully.
Next step is adding the data entity model to the solution. According to my structure of projects, I should add it to the BASample.Data project, the Model folder (Select Folder - Add New Item - ADO.NET Entity Data Model).
I select existing database, uncheck 'Save entity connection settings in App.config' (I will explain why a bit later) and copy connection string into buffer. On the next page I select all required tables (In my sample there is only one table, which will be used for authentication), enter a namespace for model BASample.Data.Model and click Finish.
Note: Only tables with primary key will be added to the model.
After adding model into the middle tier, I'm going to update .Net Ria Services link in the BASample.Data.Silverlight application (it should be set to BASample.Data).
Before moving services from web library, I should extract Ria context class from auto-generated class into separate one because an instance of Ria context must be only one for the whole silverlight application and shouldn't be placed anywhere except BASample.Silverlight project (similar to HttpContext for web applications).
I just add a new class RiaContext into BASample.Silverlight and put there source code for that class.
After successful adding .NET RIA Services Class Library to the solution I'm going to move service functions from web application into BASample.Data.
First of all, I add a folder DomainService into BASample.Data. This folder will contain all service classes that will work with data model directly. Then I add all required services into that folder (Select Folder 'Domain Service' - Right mouse button click - Add New Item - Domain Service Class) one by one. For example, table AppUser is mapped to AppUserService service class (I want to have separate class for each entity).
Fig. 5. This dialog allows to set properties for adding domain service classes.

Added class will be used instead of UserRegistrationService (see BASample.Web project).
Next step is adding Authentication service (Select Folder 'Domain Service' - Right mouse button click - Add New Item - Authentication Domain Service).
Fig. 6. This dialog allows to add new Authentication domain service class.

After step above, I go to the main Silverlight project BASample.Silverlight and add a reference to the BASample.Data.Silverlight project because it contains auto-generated class based on services of BASample.Data.
Then I start replacing invocations of old service functions with new ones. After that, I remove a .Net Ria Services link to BASample.Web from BASample.Silverlight and all service classes in BASample.Web can be excluded from the project. Also, auto-generated class can be deleted from BASample.Silverlight project.
First one appeared after moving Authentication service from BASample.Silverlight project. So, I had to initialize authentication context of the silverlight application manually. There are two ways to do it: via app.xaml and via app.xaml.cs:
Sample of app.xaml file. Authentication context initialization is highlighted.
<Application.ApplicationLifetimeObjects>
<app:RiaContext>
<app:RiaContext.Authentication>
<appsvc:FormsAuthentication DomainContextType="Pausoft.AuthSample.Data.DomainService.AuthenticationContext, Pausoft.AuthSample.Data.Client, Version= 1.0.0.0"/>
<!--<appsvc:WindowsAuthentication/>-->
</app:RiaContext.Authentication>
</app:RiaContext>
</Application.ApplicationLifetimeObjects>
Sample of app.xaml.cs file. Authentication context initialization is highlighted.
private void Application_Startup(object sender, StartupEventArgs e)
{
this.Resources.Add("RiaContext", RiaContext.Current);
((DomainAuthentication)RiaContext.Current.Authentication).DomainContext = new AuthenticationContext();
this.RootVisual = new MainPage();
}
Second issue was related to database and connection string. 'Add new data entity model' dialog allowed to store connection string into .config file and I warned about it and proposed to copy connection string into the buffer. The root of that issue is the connection string needs to be available at the runtime of the web application. It means the connection string in app.config file of BASample.Data.Silverlight will not be read by the web application and it will raise an exception "The specified named connection is either not found in the configuration, not intended to be used with the EntityClient provider, or not valid.".
This issue can be resolved by moving (adding) connection string to web.config file of BASample.Web project.
Sample of web.config file. Connection string is highlighted.
<connectionStrings>
<add name="AuthSampleEntities" connectionString="Past_Connection_String_Form_Clipboard_Here" providerName="System.Data.EntityClient" />
</connectionStrings>
Some other issues you can find during the work on silverlight business applications:
BASample.Data project to get access to services operations. Identity fields than these fields must have appropriate properties in data model:
<Property Name="Id" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
To implement custom authentication, I should override some virtual methods in AuthenticationService class. First of all, I should override methods for initialization and destroying and add a reference to AppUserService (I will use it for checking username/password).
private AppUserService appUserService = new AppUserService();
public override void Initialize(DomainServiceContext context)
{
appUserService.Initialize(context);
base.Initialize(context);
}
protected override void Dispose(bool disposing)
{
if (disposing)
this.appUserService.Dispose();
base.Dispose(disposing);
}
Then I should override methods that implement user's validation.
protected override bool ValidateUser(string userName, string password)
{
return appUserService.IsValidAppUserNamePassword(userName, password);
}
protected override UserIdentity GetAuthenticatedUser(IPrincipal principal)
{
UserIdentity user = CreateUser();
if (this.appUserService.DoesAppUserExist(principal.Identity.Name))
{
AppUser appUser = appUserService.LoadAppUserByName(principal.Identity.Name);
user.Name = appUser.Name;
user.AuthenticationType = principal.Identity.AuthenticationType;
}
return user;
}
So, these changes allow to easily implement custom authentication for any business application.
Ria services are based on Rest protocol, so it does not encrypt data transfer between the client tier and the middle tier.
Nevertheless, Ria services has got some built-in options to support secure connection. For example, the EnableClientAccess attribute of each service class has argument RequiresSsl. That boolean attribute means whether a class can only be accessed using https. This feature is very important for services that work with secure data (e.g. authentication service, financial data etc.).
Note: Visual Studio built-in web server (Cassini) does not support https protocol. So, IIS should be used instead.
Sample of using EnableClientAccess to secure all operations of AuthenticationService class.
[EnableClientAccess(RequiresSsl = true)]
public class AuthenticationService : AuthenticationBase<UserIdentity>
{
...
}
Note: If I use https for the silverlight's hosting application (BASample.Web), the same protocol will be used for the communication between the silverlight's client and the middle tier no matter what argument was used for the EnableClientAccess attribute.
To use advantages of a secure connection, I should install a secure certificate into IIS.
The easiest tool to create and deploy the secure certificate is SelfSSL (you can find it in the Internet Information Services (IIS) 6.0 Resource Kit Tools). This tool works well with IIS 5.1 also.
I use following command line to install self-signed certificate:
selfssl.exe /T /V:730 /S:1
Identifier in the list of web sites. As mentioned above, AuthenticationService will use https connection only. But the silverlight application is loaded by http protocol. That means the application calls a service from another domain (two applications that use http and https protocols are in different domains though they are hosted in the same virtual folder) and it is a cross-domain scenario.
By default, the cross-domain scenario is not allowed and the application will not work. To avoid that issue, I'm going to create clientaccesspolicy.xml. That file contains instructions about what external services can get access to the services.
Sample of clientaccesspolicy.xml file.
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
The example above allows to get access from any external domain.
I put this file in the root of the web site (not the root of my application!). When silverlight application tries to get access to the services via secure channel, this file will be read and it will allow the service to work with a request from the silverlight application.
Note: If I use https for the silverlight's hosting application (BASample.Web), the file clientaccesspolicy.xml will not be loaded because the client tier and the middle tier are working in the same domain.
Note: If If you are planning to allow to non-silverlight clients to get access to you services, you have to use crossdomain.xml file also. See description of that file here.
Source code of the application contains all described above techniques and ready to be compiled and deployed. There are some things developer should change before running:
web.config; This application allows to open login dialog, enter correct credentials and be authenticated based on credentials in the database. After that, a user can logout. Also, the application allows to add new member in the database and use added credentials for logging in.
Fig. 7. The application was accessed via http protocol but Authentication service was accessed via https.

Fig. 8. The application was accessed via http protocol but user was successfully authenticated via https protocol.

Fig. 9. User registration dialog.

Fig. 10. User's registration information was successfully added to the database (via http protocol) and user was successfully authenticated via https protocol.

This article is oriented on developers and architects, who work on business applications. It describes:
| You must Sign In to use this message board. | ||||||
|
||||||
|
||||||
|
||||||
General
News
Question
Answer
Joke
Rant
Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads.
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 7 Nov 2009 Editor: Smitha Vijayan |
Copyright 2009 by Max Paulousky Everything else Copyright © CodeProject, 1999-2010 Web11 | Advertise on the Code Project |