Dan Wahlin has a great introductory article on RIA Services in Dr. Dobbs and in Information Weekly.
Enjoy!
Dan Wahlin has a great introductory article on RIA Services in Dr. Dobbs and in Information Weekly.
Enjoy!
At Mix10 this morning in Vegas ScottGu announced that Silverlight 4 and RIA Services RC are available for download now! These bits work great with VS2010 RC.
We have some great videos, and updated samples already posted on http://silverlight.net/riaservices
Deepesh has a great list of what is new in this drop RIA Services RC and Toolkit March 2010 now available… and there is the official forum post from DineshKu RIA Services Road to RTW via RC at MIX.
INDEI Support:- Validation support based on Silverlight 4’s INotifyDataErrorInfo. This is a non-exception-based model and enables async validations more easily. It also helps display errors flagged by the server in the UI.
Spiffier DDS: filter/sort/group descriptors support binding; ICommand support for Load/SubmitChanges/RejectChanges
Server throttling: you can regulate the per request load on the server / DB by specifying maximum result limit on a query method using the QueryAttribute.ResultLimit property.
AuthorizationContext: Similar to ValidationContext, now you have more options for implementing custom authorization rules (e.g. entity-based authorization)
Endpoint configuration support: Following the “secure by default” principle, only binary endpoint will be exposed but we have made it really easy to add additional/different endpoints if you plan to use them.
OData endpoint: you can point PowerPivot to a DomainService OData endpoint and analyze data by calling the appropriate query method. This is the first step in lighting up OData with RIA Services
Download the bits now and lets us know what you think!
With Silverlight 4 and RIA Services all-but done, I thought it would be worthwhile to highlight some of the key features of the platform and tools that make Silverlight a fantastic platform for building business applications. I’ll avoid gratuitous video and dancing hippos and focus on just the bread and butter of business applications: Querying, Updating, Validating and securing your important business-data. I’ll also use this to refresh a few of the posts from my Silverlight 3 era series.
The walk through requires:
You can download the completed application.
I authored this with Silverlight 4 RC, but I fully expect it to work with Silverlight 4 RTM.
To kick off our series, I wanted to focus on our goal of helping you focus on your business, not plumbing code. The first place you will see this in the pre-build components in the Business Application Template. It describes a prescriptive application structure, looks great and is easily customizable.
After you have successfully installed Silverlight 4 for developers (which includes RIA Services) you will have a couple of new projects in the Silverlight section. We are going to focus on the Business Application Template.
Notice this creates a single solution with two projects. BusinessApplication1 is the client part of the application and BusinessApplication2 is the server part. These are related projects that know about each other.
And by default you get the framework for a great looking, professional application
The starter application is fully localizable and customizable. For example, I want to change the name of the application from “Application Name” to My Foodie Explorer. This is easily done in the Assets\Resources directory be editing the ApplicationStrings.resx file.
Check out a deeper walk through, it is a bit older, but it is still valid and Tim recently posted SNEAK PEEK: New Silverlight application themes such as:
enjoy!
To continue our series I wanted to look next at how to expose your data from the server side of your application.
The interesting data in your business applications come from a wide variety of data sources. From a SQL Database, from Oracle DB, from Sql Azure, from Sharepoint, from a mainframe and you have likely already chosen a datamodel such as NHibernate, Linq2Sql, Entity Framework, Stored Proc, a service. The goal of RIA Service in this release is to make it easy to work with data from any (or many) of the sources in a seamless way from a Silverlight application. This walk through will use Entity Framework accessing the Sql Express database, but the basic concept applies to any data source.
Add DishView.mdf to BusinessApplication1.Web\App_Data – Of course in a real world example, you’d just have a connection string to an existing database.
Then create an Entity Framework model on top of it.
As you can see, we have a very simple Entity set.. each Restaurant can have any number of Plates.
Next, we need to write some business logic that controls and shapes how to data is seen by the Silverlight client. To do that, we add a new DomainService. A DomainService is simply a special kind of WCF service that makes it MUCH easier to query, update, secure and validate your data. But if you are a WCF expert and know all the ins-and-outs of configuring a WCF service, you can certainly customize this service in exactly the same way to match your needs. Of course, in the 90% case we hope you will not need to do that.
Next we are given a chance to pre-populate the DomainService.
In this case, we will expose Plate and Restaurant, but only Plate will be updatable. We will also generate a metadata class for hanging validation attributes on so that you can regenerate the EF model without losing any customizations. We get a starter DishViewDomainService class. I have updated it in lines 8-9 with a bit of business logic. Let’s walk through each line..
1: [EnableClientAccess]2: public class DishViewDomainService : LinqToEntitiesDomainService<DishViewEntities>3: {4:5: public IQueryable<Restaurant> GetRestaurants()6: {7: return this.ObjectContext.Restaurants8: .Where (r=>r.Region != "NC')9: .OrderBy(r=>r.ID);10: }11:
Line 1: This attribute marks the DomainService as accessible over http, without it, the service is only callable from in process. This is useful in the ASP.NET WebForms\Dynamic Data scenario.
Line 2: We drive this class from the LinqToEntitiesDomainService this is a utility class that provides a few helpers for working with EF. The real work is done by the DomainService base class, this is the class you derive from for POCO and other custom scenarios.
line 5: Notice we are returning a IQueryable of our DAL Restaurant type. IQuerable is the interface LINQ is built on. This enables query capablities from the client so you can do things like sorting, paging, filtering from the client and have it compose with your custom business logic and execute on the data tier.. This means no extra data is sucked into the mid-tier or the client, but you don’t have gunk up your business logic to deal with that.
Line 8-9: we have some business logic that weeds out any Restaurant in North Carolina and puts a default ordering on the results. You can of course imagine more interesting business logic.
To continue our series, let’s see where the fun comes in my look at how easy that is to consume from the client. First just to help you understand what is happening behind the covers, let’s look at a code-behind solution. In View\Home.xaml put a simple DataGrid on the form.
<sdk:DataGrid Name="dataGrid1" Height="152" Width="692" />
Then add these lines of code to Home.xaml.cs
1: var context = new DishViewDomainContext();2: this.dataGrid1.ItemsSource = context.Restaurants;3:4: context.Load(context.GetRestaurantsQuery());5:
In line 1, we create a DishViewDomainContext… notice this is the automatically generated (via an MSBuild task) from the DishViewDomainService on the server.
In line 2, Notice we have a Restaurants property – we provide this because there is at least one query method that returns restaurants. Notice the cool binding magic, we have not yet populated this data from the server, but we go ahead and bind it. This avoids any kind of complex callback logic.
In line 4, we explicitly load the data.. this is the network call, so we want to make sure it is clear to the developer when this happening. As an argument we pass exactly which query method (and any arguments) to use.
Now we run it and we get our data..
Very painless, but it gets even easier ;-)
Go and in delete this code and the Xaml.. Then notice the DataSources window
Notice this is simply a visual representation of exactly what we were doing in code.
Notice i can change what default UI to generate and which query method to use.
Dragging Restaurants to the form and bingo, we have our data.
Run it and we have our data… what could be easier?
Click on the column headers – notice sorting works! There is no code you had to write on the client or server to enable it. This just comes for free out of returning an IQuerable.
Now let’s add paging..
First we drag and drop the DataPager control to the form, then do a bit of layout and we end up with something that looks nice
But we still need to wireup the DataPager to the same underlying DataSource. This is easy enough done by draging and dropping the same Restaurant element from the DataSources window to the DataPager. You will now you did this right if the DataPager becomes enabled.
Notice that paging works great! No code needed on the client or the server, again, all done through using that simple Linq query we wrote on the server. But what about paging AND sorting… do they work well together? Will it just sort the page of data that is loaded locally? The answer of course is that sorting and paging compose nicely together and the sort is actually sent all the way to the data tier and executed there in a very efficient way.
Now let’s add filtering. With just a bit more work in the UI, we can add a way to filter by postal code.
<sdk:Label Name="label1" Content="Postal Code:" FontSize="14" Margin="0,0,462,13" /><TextBox Height="23" HorizontalAlignment="Left" Margin="110,12,0,0" Name="postalCodeTextbox" VerticalAlignment="Top" Width="120" />
Then we need to wire this up to the query. Of course we want the filter applied as close to the data as possible. We don’t want to download all the entities locally, then filter, nor do we want to pull them all to the middle-tier and then filter. What we want is for the filter to be applied at the database level. Luckily this is very easy to do with LINQ composition.
First we select the DomainDataSource in the Document Outline view.
Operator – typically you should set this to “Contains”. If you use the default of “IsEqualTo” the first load (when there is no filter) will result in no results returned.
PropertyPath – this is the property on the entity that you are filtering on… Just type in the simple name.
Value – this is where to get the value to compare from. It is easiest to do UI-to-UI binding to the TextBox’s Text property.
Here is the dialog once we are done:
And the resulting Xaml:
<riaControls:DomainDataSource Name="restaurantDomainDataSource" AutoLoad="True"d:DesignData="{d:DesignInstance my:Restaurant,CreateList=true}"Height="0" Width="0"LoadedData="restaurantDomainDataSource_LoadedData_1"QueryName="GetRestaurantsQuery"><riaControls:DomainDataSource.FilterDescriptors><riaControls:FilterDescriptor Operator="Contains"PropertyPath="PostalCode"Value="{Binding ElementName=postalCodeTextbox, Path=Text}" /></riaControls:DomainDataSource.FilterDescriptors><riaControls:DomainDataSource.DomainContext><my:DishViewDomainContext /></riaControls:DomainDataSource.DomainContext></riaControls:DomainDataSource>
Notice no code changes at all, and no changes to the business logic in the DomainService in particular.
OData is an emerging set of extensions for the ATOM protocol that makes it easier to share data over the web. To show off OData in RIA Services, let’s continue our series. We think it is very interesting to expose OData from a DomainService to facilitate data sharing. For example I might want users to be able to access my data in a rich way in Excel as well as my custom Silverlight client. I’d like to be able to enable that without writing multiple services or duplicating any business or data access logic.
This is very easy to enable with RIA Services. In fact it is just a check box away! When you create your DomainService simply check the “Expose OData endpoint” and that will expose your DomainService as an OData feed.
If you have already created a DomainService it is easy to enable OData on it as well by doing the two things this wizard does.
First, it adds an endpoint to the domainServices section of the web.config.
<system.serviceModel><domainServices><endpoints><add name="OData"type="System.ServiceModel.DomainServices.Hosting.ODataEndpointFactory, System.ServiceModel.DomainServices.Hosting.OData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" /></endpoints></domainServices>
Second, on each paramaterless query methods you wish to expose via OData, mark the query as being default. Meaning any time there is an ask for “Plate” it is this query method that is used.
[Query(IsDefault = true)]public IQueryable<Plate> GetPlates(){
once these are done, you an hit the service and see an Atom feed. The format of the URL is the namespace+typename for the domainservice with dots replaced by dashs followed by “.svc/Odata/”. So if the DomainService class is
MyApp.Web.DishViewDomainService then the URL would be http://localhost:30045/myapp-web-DishViewDomainService.svc/OData/
http://localhost:30045/myapp-web-DishViewDomainService.svc/OData/PlateSet
And then drill in with this URL: http://localhost:30045/myapp-web-DishViewDomainService.svc/OData/PlateSet
That is really cool that the data is in an open ATOM based format… but what is even better is there is a budding ecosystem of clients that can consume this feed. One of the more interesting ones is the Excel addin called PowerPivot.
Once you have it installed with Excel 2010. select the PowerPivot window
Then you can use the full power of excel so if i want to sort by Number of Updates, with a rating of 4 or higher, with calorie count between 3000 and 4000 then go graph that in some interesting way, you can do the easily.. All with the live data without any custom application code.
What we showed in this walk though is how to expose OData from your DomainService and consume that in Excel. This is just a down payment on the OData support coming in the future in RIA Services.