Using a DomainService in ASP.NET and Dynamic Data
One of the big things that I discussed in my MIX talk is the new DomainDataSource control. It is currently available in Preview form as part of ASP.NET Dynamic Data 4.0 Preview 3. This can be confusing, because even though Dynamic Data makes use of DomainDataSource, DomainDataSource is absolutely not tied to Dynamic Data, and is fully usable in ‘regular’ aspx pages.
In addition to this preview, you’ll want to also install Microsoft .NET RIA Services in order to get some useful tooling. This too can be confusing, because it makes it sound like it’s tied to RIA and Silverlight in some way, when in fact it is not.
The deal is that there is this new thing called a DomainService, which is essentially a Business Layer class that exposes CRUD methods. Once you have a DomainService, you can use it in various scenarios, including ASP.NET apps and Silverlight apps. Here, we will focus on its use from ASP.NET. For more information about the Silverlight side of things, check out Nikhil’s post (and his MIX talk).
Important: after getting the ASP.NET DD preview and the RIA Services mentioned above, you’ll need to do a little extra step to avoid a tricky setup issue. Find System.Web.DynamicData.dll under DefaultDomainServiceProject\bin in the ASP.NET Preview zip file, and copy it over the one in \Program Files\Microsoft SDKs\RIA Services\v1.0\Libraries\Server (which is where the RIA install puts them).
Now you’re actually ready to start playing with DomainService.
First, you’ll want to make a copy of the whole DefaultDomainServiceProject folder so you can work with it without touching the ‘original’. Then, just open DefaultDomainServiceProject.sln in VS. Normally, this would be a Project Template, but right now we don’t have one.
Creating a DomainService
DefaultDomainServiceProject comes with a default DomainService, but to make things more interesting you should just delete it and recreate one from scratch. Just delete DomainServices\NorthwindEntitiesDomainService.cs.
Now right click on DomainServices, choose Add New Item, and pick Domain Service Class. Name it for instance Catalog.
You’ll see a New Domain Service dialog. In here, do the following:
- Uncheck Enable Client Access. That’s only useful for the Silverlight scenario.
- Check Categories and Products. For Products, also click the right check box to enable editing.
- Check ‘Generate associated classes’ at the bottom. This will be useful for Dynamic Data.
You should end up with a class that looks like this:
public class Catalog : LinqToEntitiesDomainService<NorthwindEntities> {
public IQueryable<Categories> GetCategories() {
return this.Context.Categories;
}
public IQueryable<Products> GetProducts() {
return this.Context.Products;
}
public void InsertProducts(Products products) {
this.Context.AddToProducts(products);
}
public void UpdateProducts(Products currentProducts, Products originalProducts) {
this.Context.AttachAsModified(currentProducts, originalProducts);
}
public void DeleteProducts(Products products) {
if ((products.EntityState == EntityState.Detached)) {
this.Context.Attach(products);
}
this.Context.DeleteObject(products);
}
Basically, it’s just a class for a few CRUD methods that you want to expose. In this case, it’s working over an Entity Framework model (hence the base class), but it would look similar with Linq to SQL or other ORM technologies.
The important part is that all data access goes through those methods, so you have full control over it. This is quite different from using LinqDataSource/EntityDataSource, where they talk directly to the DAL without going through your code. You have to write a little code, but the extra control you get makes it well worth it!
Registering your DomainService with Dynamic Data
Before we get into writing ‘standard’ ASP.NET pages by hand (in future posts), we’ll use Dynamic Data to get started quickly. To do this, simply add this line to global.asax (replacing the similar line that’s already there):
DefaultModel.RegisterContext(
new DomainModelProvider(typeof(Catalog)),
new ContextConfiguration() { ScaffoldAllTables = true });
Running it
Now you can just Ctrl-F5 and you should get a working Dynamic Data app. Note how it only lets you do things for which you have CRUD methods. e.g. you can edit Products but not Categories.
To make things more interesting, try various things:
- Debug the app and set break points in your CRUD methods to see them getting called.
- Change GetProduct() to only return a subset of the products, and watch it affect the UI
- Change UpdateProduct() to modify the product before saving it,
- Add some Dynamic Data style metadata in DomainServices\Catalog.metadata.cs. e.g. add a [Range(0, 100)] attribute to some integer field, and try an edit that violates the range
Conclusion
This was really just a quick intro to using DomainService in ASP.NET and Dynamic Data. I’ll try to follow up with some posts that go into more details on how to use DomainDataSource directly in a page without involving any Dynamic Data. To reiterate, though Dynamic Data works great with DomainDataSource, DomainDataSource completely stands on its own without Dynamic Data (as was shown in my MIX talk).