Things you can do with WCF RIA Services and a regular .svc file
Let’s say you create a new DomainService called TasksDomainService and host this service in an ASP.NET website.
The HttpModule DomainServiceModule will make sure you can access this service as if a physical .svc file was present on the webserver. It will take the namespace and the class name (in my case Sandworks.Silverlight.nTier.Services and TasksDomainService), combine them and append ".svc".
In my case I could access the service via: http://localhost:9346/Sandworks-Silverlight-nTier-Services-TasksDomainService.svc
But what to do when you want a cleaner url (http://localhost/Tasks.svc for example)?
This is possible, just follow these steps:
- In the web project containing your service, create a new file: Tasks.svc
- Open this file
- Enter the following:
<%@ ServiceHost Service="Sandworks.Silverlight.nTier.Services.TasksDomainService" Factory="System.ServiceModel.DomainServices.Hosting.DomainServiceHostFactory, System.ServiceModel.DomainServices.Hosting, Version=126.96.36.199, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
The markup you see in step 3 tells the server what service to load (Service, this needs to include the namespace) and how to load it (Factory, the DomainServiceHostFactory will correctly host your DomainService class).
If you don’t use the fully qualified assembly name this will result in the following error (thanks Luc!):
Parser Error Message: The CLR Type ‘System.ServiceModel.DomainServices.Hosting.DomainServiceHostFactory’ could not be loaded during service compilation. Verify that this type is either defined in a source file located in the application’s \AppCode directory, contained in a compiled assembly located in the application’s \bin directory, or present in an assembly installed in the Global Assembly Cache. Note that the type name is case-sensitive and that the directories such as \AppCode and \bin must be located in the application’s root directory and cannot be nested in subdirectories.
Do read Rick’s post if you also want to remove the .svc extension to go RESTfull: http://www.west-wind.com/weblog/posts/570695.aspx
Clean project structure
When creating a new solution I love to organize a clean project structure.
But when you’re using Silverlight with WCF RIA Services this can be challenging though.
This is what we’ll try to accomplish:
A little word on the projects:
- Sandworks.Silverlight.nTier.Client: The Silverlight application.
- Sandworks.Silverlight.nTier.Client.Model: A regular Silverlight Class Library with a WCF RIA Services link.
- Sandworks.Silverlight.nTier.Services: A WCF Service Library.
- Sandworks.Silverlight.nTier.Services.Host: A WCF Service Application.
- Sandworks.Silverlight.nTier.Web: This hosts the Silverlight application.
Note, we won’t be using a WCF RIA Services Class Library because the namespaces and assembly names are not so clean (.Web is appended to your server side class library):
Here are the steps you need to follow to create your own clean project structure:
- Open Visual Studio, select File, New Project
- Select Silverlight Application
- Enter the following:
- Visual Studio will ask you to host the application in a new ASP.NET Web Site.
Make sure you change My.Application.Client.Web to My.Application.Web and press OK (do not check Enable WCF RIA Services).
- Add a new Silverlight Class Library called My.Application.Client.Model and remove Class1.cs
- In your project My.Application.Client add a project reference to My.Application.Client.Model
- Add a new WCF Service Library called My.Application.Services and remove all files.
- Add a new WCF Service Application called My.Application.Services.Host and remove the fake Service1.
- In your project My.Application.Services.Host add the following references:
My.Application.Services (project reference)
- Rebuild your solution.
- In your project My.Application.Client.Model go to Properties and add a WCF RIA Services link to My.Application.Services This will make sure the code generation is in place.
- Create 3 solution folders: Client, Services, Web and reorganize your projects.
And you’re done:
The only things left to do are:
- Create a new Domain Service Class in My.Application.Services
- Create a .svc file in My.Application.Services.Host (referencing that class, see start of this post)
- Rebuild your solution (code generation will take place in My.Application.Client.Model)
- Use your service context in My.Application.Client
- Configure the web applications on a fixed port (easier for when you’re debugging).
Since your service isn’t in the same project/Virtual Directory as the Web project you’ll have to explicitly declare the url:
TasksDomainContext ctx = new TasksDomainContext(new Uri("http://localhost:10001/Tasks.svc"));
In a following article I’ll explain how to configure these urls.
But for now here are the downloads:
- Example with a working service: Sandworks.Silverlight.nTier.zip (464.99 kb)
- My.Application example: My.Application.zip (48.44 kb)