MIX10 Talk - Slides and Code

Another exciting MIX ... this post contains references to slides and code for my RIA Services session/demo - the BookClub application...

At MIX10, I presented the Developing with WCF RIA Services Quickly and Effectively talk. For the demos I used a BookClub application - the scenario is a team application for team members to use to share books and browse/search/request shared books.

Book Club - Browsing View Book Club - Bookshelf View

The following are the concepts that the demos and code cover:

  • CRUD (editing your shared books) using the domain service pattern in the BookShelfService implementation, along with both convention and configuration.
  • Using LINQ across client and server, and working with EntityQuery object on the client, to implement both filtering and "More"-style paging.
  • Validation via declarative metadata and imperative rules.
  • Reference data pattern for implementing lookup comboboxes.
  • Custom DomainServiceFactory implementation for customizing instantiation of domain services in the application.
  • Custom authentication service implementation (that authenticates and validates user credentials using a Members table in the data model rather than ASP.NET Membership).
  • Custom authorization rules (see CustomAuthorizationAttribute, just like validation)
  • ViewModel pattern, aka MVVM, to complement RIA Services, and how you can design view models starting from your user interface or a sketch of a prototype.
  • Taking DomainServices to the next level by using presentation model or projected types (see how BookClubDomainService exposes BookInfo entities that is a projection over multiple tables in the underlying data model).
  • Aggregating data from multiple sources (database and Amazon service) within a single DomainService.
  • Invoking and using stored procedures within a DomainService.
  • Implementing Invoke operations, i.e. non-CRUD operations alongside the CRUD pattern (see the RequestBook operation on BookClubService).
  • Reusing the domain service across different front-end applications and screens. Specifically I had a Windows Phone 7 application that used a regular SOAP interface to the same domain service to access the BookClubService.

Book Club on the Go - Windows Phone 7 application Book Club on the Go - Windows Phone 7 application

I tried to approach this sample with an eye toward how a real-world application might be built when using RIA Services, based on my blog post before the talk and some of the comments that were posted. I realized there was way more than enough content, but decided to keep the sample as-is for the purposes of sharing it out.

I’ll be blogging many of these bullets listed above with more details in subsequent individual posts, so stay tuned. However, for now you can browse through the code, and the slide deck to get some sense of the concepts. Note that you’ll need to create the database using the included SQL script, and specify your very own Amazon ID and secret key in web.config to run the samples.

I’m on twitter (@nikhilk) if you’d like to connect and be part of the conversation. As always, comments, as well as questions, are welcome below.

Posted on Sunday, 3/21/2010 @ 10:51 PM | #Silverlight


Comments

52 comments have been posted.

rolls

Posted on 3/22/2010 @ 12:00 AM
Hi.... getting this error when I load up
Unable to read the project file 'BookClub.Web.csproj'.
C:\Users\Royce.Royce-Laptop\Documents\Downloads\BookClub\BookClub\BookClub.Web\BookClub.Web.csproj(39,7): The project file could not be loaded. The 'ItemGroup' start tag on line 35 position 4 does not match the end tag of 'Reference'. Line 39, position 7.

Regards

Glenn Block

Posted on 3/22/2010 @ 1:33 AM
Loved this talk Nikhil, in particular the way you broke down MVVM into very clear terms. That method binding command looks nifty.

Nikhil Kothari

Posted on 3/22/2010 @ 2:00 PM
@Rolls
I uploaded an updated zip with the project issue fixed later in the night. Hopefully things are working now...

John Waters

Posted on 3/22/2010 @ 4:09 PM
Hi Nikhil,
Thanks so much for the talk and the code, it was extremely helpful.
You mentioned there was a bug in the generation of the setter for the entity references, do you have an ETA for when a fix would be available?
Also, I do have a question about lookups, I would love to hear your thoughts on your solution:
Say in your example you have 10 categories, and 100 books. You load your 10 categories up front, and then the user starts paging through the books, which get hooked up to their categories.
Now, imaging, another user creates a new category, and adds 10 books for that new category
Your first user reaches those books, and now doesnt have a match for the new category.
How would you solve that? At the point it is discovered a category is missing, it is too late to fetch it, especially given the async nature of things....
Cheers
John

Nikhil Kothari

Posted on 3/22/2010 @ 6:09 PM
@John
The bug fix would be available in the final v1 release of ria services.

As for your scenario of dynamic categories - it depends on your app, how common such things are - if the data is pretty static, you're set. However if your reference data is actually dynamic, there are probably multiple approaches. Two I can think of right now:
1. For very dynamic scenarios, implement polling, or server "push" - hopefully will be more integrated into ria services.
2. For less dynamic scenarios, detect if there is new reference data by looking at entities that got loaded, and seeing if their references resolve. If they don't you're reference data needs to be refreshed. Even though that will happen in an async manner, when the reference data loads up, things will resolve on the basis of foreign keys.

Maxim

Posted on 3/23/2010 @ 7:13 AM
Wow, man, awesome presentation. Thanks. It really made clear a lot of aspects for me.

John Waters

Posted on 3/23/2010 @ 1:44 PM
Thanks,
One thing that might make it helpful would be if the client side EntitySet class had a EntityLookMiss event that would fire when a lookup failed, passing the key of the missed lookup. Then the developer could handle that to perform whatever kind of refresh that the business logic dictated?
John

Slashxxx

Posted on 3/25/2010 @ 10:13 PM
Hey Nikhil, great talk, tyvm!!

I'm trying to run up your app and having trouble with your web service connecting to my sqlexpress database running locally on win7 with a default install.

I manually created the BookClub db using sqlsrv mgmt studio 2008 then executed your supplied script with no errors. Queries are working fine in sql server studio.

The error I get is

"A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)"

Santos Ray Victorero, II

Posted on 3/26/2010 @ 6:30 AM
Excellent presentation!

Nikhil, do you know if there is going to be an ASP.NET MVC based version of the Silverlight Business Application in the final release?

@Slashxxx
I had a similar situation and running VS 2010 as administrator solved my problem.

Santos

Nikhil Kothari

Posted on 3/26/2010 @ 8:09 AM
@Slashxxx (and others using the sample)

The connection string in the sample is for the local sql server, where you make a db called BookClub and run the sql script included in the zip to initialize with schema and data.

You should be able to use SQL Express too, but you'll need to change the connection string to point to the database you create accordingly.

Santos Ray Victorero, II

Posted on 3/26/2010 @ 11:56 AM
My previous post should say: "ASP.NET MVC based version of the Silverlight Business Application template", because the current one only allows ASP.NET for the server project.

Thanks anyway!

Santos

Nikhil Kothari

Posted on 3/26/2010 @ 2:00 PM
@Santos
Right now there isn't a plan to also have an MVC version. I'll pass along your comment to +1 that request.

The only thing I can suggest for now is create an MVC project, and then add a Silverlight navigation app, and when prompted check the WCF RIA Services checkbox for the Silverlight app to link the two projects together.

Santos Ray Victorero, II

Posted on 3/26/2010 @ 7:58 PM
Nikhil,

Thanks for the suggestion; it does the trick very close. I used an existing ASP.NET MVC project, created a Silverlight application using the navigation template as you said and then selected the ASP.NET MVC project in the combobox, then I created a temporary Silverlight application using the Business Application template and copied the rest of the folders to the ASP.NET MVC project (Resources) and to the Silverlight project (Controls, Helpers, etc).

After some renaming it works like a charm. :-) Although it will be nice to have a template!

Regards,

Santos

Ben Hayat

Posted on 3/27/2010 @ 2:26 PM
Hi Nikhil;
I posted this message once and somehow I don't see it posted; So I'll Start Again;

After downloading the latest copy I then:
a) Created the database
b) Ran the SQL Script to build data. I can see it
c) Updated the Web.config Connection string and also put my Amazon keys there.

Now when I run the app, I see the MainPage for one second in IE and then goes away. In FF 3.62 the page stays but can't see any data

Note: I also don't see any authorization DB in the project APP_Data section.

Ben Hayat

Posted on 3/27/2010 @ 3:01 PM
FYI, I'm able to run the store Project, but not the book club.
Thanks!

Ben Hayat

Posted on 3/27/2010 @ 8:47 PM
Nikhil, it seems like when the code is going through the Command.cs and once it passes line 119 it crashes there. I see the BookClub xaml gets loaded and displayed and then starts going through BookClub.Model.cs and once it jumps to Command.cs the "ICommand.CanExecute()" method bums out.

Hope this helps!

Ben Hayat

Posted on 3/27/2010 @ 10:20 PM
Looking at BookShelf.Xaml and BookClub.xaml, I see neither one has the DataContex set for the Designer as what type it is. I'm not sure if this the cause of the problem. I've also noticed that upload code is somewhat different than the one from your session.

Just trying to offer some clues as to what the problem might be.
Sorry for too many posts! :-)
..Ben

Bart Bories

Posted on 3/30/2010 @ 11:53 PM
Is there a way to open the project in vs2008?

thx

Braulio

Posted on 3/31/2010 @ 10:17 AM
Hi Nikhil,

Same issue, page shown for a second then redirected to blank screen, constructor of booksModel, call to ShowBooksOfDay();, commenting this I get no white screen but If I try to make whatever operation again white screen... Eeehh uummm.... I think it's missing a bit of error handling here? :)

I have deployed my DB in my localhost (SQL Server 2008 Dev Edition).

Any way to fix this?

foobar

Posted on 4/1/2010 @ 11:36 AM
Alas, this is an over-engineered demo seeking to showcase numerous things at once. It would have been much, much better if the author had built the application step by step. The concomitant video isn't helpful and difficult to find one's bearings through it.

Has anybody got the application to work? For the world of me, I'm unable to do anything meaninful in the browser.

The database contains books. Suppose a user sees "Book Club -- The book of the Day, and other similar books..." plus half a dozen hyperlinks, etc. on the screen. What does the user have to do in the browser on the screen to view the books stored in the database?

Nikhil Kothari

Posted on 4/1/2010 @ 2:38 PM
@foobar

The book club app is _not_ a book club database browser. Most end users don't really care to browse a database in its raw form - they instead want to use an application for its features, and capabilities - eg. searching for books, placing requests, contributing books to the book club etc. The app is specifically meant to point out that building an app shouldn't result in a database browser.

If you as a developer want to browse the database, just browse the database using something like SQL management studio. Or if you're an admin, and want to see the raw view, that is fine too as an app scenario, but this app isn't the one that illustrates that basic CRUD scenario.

John Waters

Posted on 4/1/2010 @ 9:14 PM
Nikhil, would you mind posting that setter code for the lookups, so I can hand code that for now?

Nikhil Kothari

Posted on 4/5/2010 @ 7:21 AM
@John
Here is the code you will need to workaround the bug preventing a settable association property when the associated type is an external reference. To be clear, for the next (RTM) release, the correct code to write is simply adding [ExternalReference] on the server, and having code-generation produce this for you.

In a partial Book class, add the following code:

private EntityRef<Category> _category;
[Association("Category_Book", "CategoryID", "CategoryID", IsForeignKey=true)]
[ExternalReference]
public Category Category {
get {
if (_category == null) {
_category = new EntityRef<Category>(this, "Category", FilterCategory);
}
return this._category.Entity;
}
set {
Category previous = Category;
if (previous != value) {
if (value != null) {
this.CategoryID = value.CategoryID;
}
else {
CategoryID = default(int);
}
}
}
}

private bool FilterCategory(global::BookClub.Web.DataModel.Category entity) {
return (entity.CategoryID == CategoryID);
}

Matt Davidson

Posted on 4/5/2010 @ 8:47 AM
Nikhil,
It is a shame you didn't get a chance to cover the Presentation Model types slides (14/15), I will browse the code for the BookInfo class example but if you know of any useful guides or could complete the talk with a blog post on the topic covering the steps required to implement it that would be great. Apart from that your presentation was a great extension to much of the existing RIA examples around and will be very useful indeed.

Many thanks,
Matt Davidson

Nikhil Kothari

Posted on 4/5/2010 @ 1:39 PM
@Matt
I am looking at one or maybe both:
- A followup sample app thats a bit more fleshed out in couple of areas
- A more in-depth screencast covering the full content (probably in parts since it would be much more longer than a typical conference session).

Boris R

Posted on 4/6/2010 @ 7:16 AM
Nikhil,
I see that you are heavily relying on Command pattern which is new in Silverlight 4 (and not so new for WPF).
Personally I like this approach very much, because it provides very clear separation between the View and the Model.

But, is this something that you would recommend for application development, since it is not supported by all controls (especially not the third party ones)?
BTW, is introduction of ICommand in Silverlight just for WPF compatibility, or a strong and preferred pattern for future app design.
Thanks and Best Regards,
Boris

Boris R

Posted on 4/6/2010 @ 2:29 PM
Well, I just saw Mix10 presentation by Laurent Bugnion: Understanding the Model-View-ViewModel Pattern (http://live.visitmix.com/MIX10/Sessions/EX14) that explains pretty much everything that I previously asked.
Thanks,
Boris

Nikhil Kothari

Posted on 4/6/2010 @ 11:08 PM
@Boris
In terms of my opinion commands are useful (in the view, not in the view model). I think commands on other controls besides Button are interesting, as well as commands exposed by UI controls (eg. Frame with Back command and Forward command). So the core ICommand concept is quite relevant.

Martin Z

Posted on 4/9/2010 @ 1:02 AM
Hi Nikhik,

Great talk, great demo. I'm trying to get the BookClub app running, but can't get it to work. At build time, I get a warning: "Warning 1 Could not resolve this reference. Could not locate the assembly "Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors. BookClub.Web"

I can't find the specified assembly. I also get an exception for every query that gets send to the server: "Load operation failed for query '*'. The remote server returned an error: NotFound". Substitute any query for *. Any ideas as to what I'm missing here?

TIA,
Martin.

Nikhil Kothari

Posted on 4/11/2010 @ 1:48 PM
@Martin
Please install the RIA Services toolkit. That is where that assembly comes from.
I guess in the next update to the sample, I should just include the assemblies, as not everyone will have installed the toolkit.

Hope that gets it working for you...

Pascal

Posted on 4/18/2010 @ 4:59 PM
Hello,

I'm trying to emulate the structure of the ViewModel classes, and don't see how VS 2010 displays the Bookshelf.Model.cs file "underneath" the Bookshelf.xaml file together with the Bookshelf.xaml.cs file. I really would like to organize my ViewModel classes in the same way.

Thanks.

anthony

Posted on 4/21/2010 @ 12:27 PM
It seems to me that the source code downloaded from here is not completed. I tried to follow the video and put code into booksheft.xaml.cs file but I got stuck at the line

bookEditor.Book = (Book)bookListBox.SelectedItem;

the compiler complained that
The type name 'Controls' does not exist in the type 'BookClub.Pages.BookClub'
in BookShelf.g.cs generated file.

Also there is a lot of thing in both xaml and xaml.cs files need to be added. For instance: name of bookEditor control...

Could you please re-up the whole working code ?

Andrew

Posted on 5/3/2010 @ 2:47 PM
Did any get the issues mentioned by Ben Hayat and Braulio resolved? The one where the interface appears and then blanks after a few seconds? I've read through the posts and don't see a solution. Sorry for re-posting if there has already been an answer.

- thanks

Andrew

Posted on 5/4/2010 @ 8:10 AM
Nevermind, WCF Ria Services Toolkit installation fixed it.

Greg Hollywood

Posted on 5/15/2010 @ 7:39 AM
Nikhil,

I think your presentation is the best I have seen yet on Ria Services! It was very informative and helpful.

I am now trying to get the sample project to run. I have run the sql script and can connect to the database just fine. However, when i run the app, I get a "Not Found" error. I think the issue is that the Domain Service is not getting started on the server. For example, I put a breakpoint in the Application_Start in Global asax cs, but it never gets triggered. I put a breakpoint on the CreateDomainService, and it also never gets hit.

But the Global asax file is there with the appropriate code, so I don't see why it isn't being processed.

So what happens when you run the app is that it shows for a second, and then errors out on the ShowBooksOfTheDay which closes the screen. This is why several people above have noted that the app seems to run for a moment and then blank out.

Any assistance on this would be appreciated, as I am trying to implement the same structure as you have on your application. I know this is just a sample app for a presentation, but like Brad A's sample app, they seem to take on a life of their own!

Greg

Greg Hollywood

Posted on 5/15/2010 @ 8:21 AM
Following up the above, I can get Application_Start to run, but CreateDomainService never runs. Also, I don't quite get one thing. If the domain service requires in the constructor, does this mean that there is a different Domain service for every user? The concept I had was that there was only one Domain service which was used by everyone hitting the service.

Thanks,

Greg

Joshua

Posted on 5/17/2010 @ 10:51 AM
Would you consider maintaining the Book Club sample app in a Github (or Codeplex, or any) public source repository so we could follow the updates more easily? This would also allow you to potentially allow people to submit patches so that the burden of keeping the sample up-to-date wouldn't be all on you.

It would also be faster for us to get updates as you make them instead of having to wait for a blog post to notify us of the changes and new code.

Thanks for putting the work into such a great sample! Just hoping to expose it a bit more :)

Vinney K

Posted on 5/20/2010 @ 9:31 AM
I notice that your EF objects are being created as type Entity. My objects are of type EntityObject which does not seem to inherit INotifyPropertyChanged. Am I missing something?

Vinney K

Posted on 5/20/2010 @ 9:45 AM
...Ah, I see. The class that gets generated in the SL app derives from the Entity class.

Pete D

Posted on 5/20/2010 @ 1:44 PM
I too am having problems getting the BookClub example to work.

FIle:AmazonService.cs
Line 42: xml = webClient.DownloadString(searchUri);
Eerror: The remote server returned an error: (403) Forbidden.

If I say that this may be because one has to have some sort of account with Amazon, everyone will prabably laugh, so I won't.
Anyway, whatever the reason, it doesn't work, which is a real pity because I was hoping it would help me learn.

thomas

Posted on 5/21/2010 @ 3:55 AM
What to do when CreateDomainService never runs?!
With no instansiated DomainService the page goes blank - on start - when it tries to run the bookoftheday-routine.


t.

Slashxxx

Posted on 5/26/2010 @ 11:55 PM
Hi Nikhil,

I was able to get the app running back in March - thanks for the suggestion!

I'm coming back to do some more experimenting with WC RIA Services and WP7 trying to run the .web project on an VS2010 RTM/SL4. The issue I'm facing is when I try to run the project it tells me "This Application was created for an expired beta release of Silverlight. etc.."

Is there anything we can do ourselves to get by this until an update is released?

Slashxxx

Posted on 5/26/2010 @ 11:59 PM
ok, nevermind that - rebuild moved me past this issue.

Pete

Posted on 6/8/2010 @ 12:21 PM
Hi Nikhil,
I was just looking at the source code and noticed something strange (or at least something I've not seen or done before)... In the Pages folder, how were you able to assign two code behind files to one xaml file ? (ie both BookClub.Model.cs & BookClub.xaml.cs files are linked to the BookClub.xaml file)

Cheers in advanced

Pete

Posted on 6/8/2010 @ 1:00 PM
Ignore my last comments -mokosh's vscommands allowed me to the grouping.

Miguel Mayorga

Posted on 6/9/2010 @ 12:38 PM
Book Club demo.

Development environment, everything works Ok.

But,
Production server does not display information. What should be done in addition to publish and place on the server to function properly, and shows no data and generates Use the following :
There was an error loading the request books. Load opration failed for query GetBookOfTheDay. Object reference not set to an instance of object.

Thanks.

Nikhil Kothari

Posted on 6/21/2010 @ 7:04 AM
@Joshua
Late response... but thanks for the offer. I've actually gone ahead and created a CodePlex project since - it is http://riaservices.codeplex.com - it contains the BookClub app as a sample app for now, and will eventually contain other samples as well, depending on time.

Daniel Varrin

Posted on 7/15/2010 @ 1:53 AM
Hi Nikhil,

I'm creating a silverlight application using RIA Services and the MVVM Pattern. Instead of having a button to load more items in a list, I would like to display my items in a datagrid and use the DataPager Control in SL4. I've seen an example using RIA Services without MVVM, and it was using a cache to avoid reloading the already loaded data. On the xaml page it was using some Ria controls, but I would like to do the same using MVVM.

I'm a bit lost and don't really know what I've to do. Do I have to to the paging and caching myself?

Daniel Varrin

Posted on 7/15/2010 @ 2:04 AM
Hi Nikhil,

I'm creating a silverlight application using RIA Services and the MVVM Pattern. Instead of having a button to load more items in a list, I would like to display my items in a datagrid and use the DataPager Control in SL4. I've seen an example using RIA Services without MVVM, and it was using a cache to avoid reloading the already loaded data. On the xaml page it was using some Ria controls, but I would like to do the same using MVVM.

I'm a bit lost and don't really know what I've to do. Do I have to to the paging and caching myself?

Gaurav Bhasin

Posted on 8/12/2010 @ 12:53 PM
Hello Nikhil,

We have been working on researching RIA services for our new development initiative. Definetly found the book club application to be very useful. I was wondering how to load child entities along with the parent. For example using the book club application entity model, how would I load a Member and his respective books in one call from the client. I noticed on the client data context you can't use Include for the EntityQuery on the domainservice I used the "Include" but noticed the child entity wasn't pulled down to the client. I wouldn't want to make multiple calls to retrieve a parent and the child entities.

Thanks,
Gaurav Bhasin

Roy Lou

Posted on 9/30/2010 @ 2:28 PM
Hi Nikhil,
Our team started developing part of our existing website using Silverlight4 and we found your articles and video extremely helpful. We are glad to find your BookClub sample code [http://www.nikhilk.net/Content/Presentations/MIX10/BookClub.zip] and we are anxious to load it up. However when we try to open it from VS2010, we encountered the following challenges, which stops us from running it:
1. The solution was built successfully. However when we press F5, a web exception occurred at [WebServices\Amazon\AmazonService.cs line 42] – “xml = webClient.DowlnoadString(searchUri);” with the following error message: :The remote server returned an error: (407) Proxy Authentication Required”.
2. We got InvalidClientTokenId when we entered the absolute Url directly in the IE browser.
3. There is another project called “BookClubOnTheGo” along with “BookClub” & “BookClub.Web” However the solution did not load it and it will generate the “The project type is not supported by this installation” error message if we manually load it. What is this project?

Advice please! Thanks!

Pankaj

Posted on 1/18/2011 @ 10:54 PM
Great piece of presentation. Have a question though. How can we share subset of entity with client? In the demo you the book class was spanned as it is to the client. In a real world app you might not want to expose your domain entities as it is to the client.

Thanks
Post your comment and continue the discussion.