Resumé

RIAServices.jQuery for pure HTML Rich Internet Apps

Cristian Merighi () 0.00

Using RIA/JS for pure HTML+Javascript MVVM business applications.
This article is obsolete. Some functionalities might not work anymore. Comments are disabled.

RIAServices.jQuery (aka RIA/JS) is a Microsoft signed project that promises, in a near future, to be an affordable solution on the client MVVM frameworks' scene. I gave it credit - please dear MS don't make me repent - and decided to spend some of my "ultra-precious" time upon.
Reference site is as usual codeplex, where the project is so far defined as "In progress" and in fact upgrades seem to come out with an encouraging steady path (last in August 2011).

How the libraries that compose RIA/JS have to be used then?
Spitting out the whole truth, a project designed to "inspire" the developers already exists: it's the BigShelf project, but...

  1. Trying to make it run it's a serious pain in the back (I didn't succeed);
  2. Third party installations are necessary, but they are not relevant to RIA/JS itself (that's unfair and bad).

Ok, with that said, let's try to build up a step-by-step tutorial about the configuration of a WebApplication (RIAServices can be hosted only in this kind of web project in Visual Studio 2010) meant to use RIA/JS.

Through the super-useful package installer NuGet (for the few of those who don't know nor use it yet → nuget.org/) let us include the necessary client and server libraries:

NuGet screenshot

You can search for the online package querying «RIAServices.jQuery»,
Once you've installed the package, new items will appear in your Solution Explorer panel:

Solution Explorer

Package includes (as highlighted in the first image) jQuery 1.5.2 (last version at the moment I'm writing is 1.6.2 and works perfectly as well). Strictly related to the jQuery world also come jQuery.Templates ($.tmpl) and jQuery.Validation ($.validation), the latter is exploited when metadata get parsed (see Ln 162 @ RemoteDataSource.js).
A useful plugin not included via NuGet install is the jQuery.DataLink (api.jquery.com/link), get it. Hope to see soon a merge with the jquery.observable API.

Please notice the reference added to the Microsoft.ServiceModel.DomainServices.Hosting.dll assembly, along with the modifications to the Web.config file (see code-snippet below).

What gets modified in the Web.config: A Json EndPoint gets enabled for the RIAService:

Web.config:
  1. <system.serviceModel>
  2.     <domainServices>
  3.       <endpoints>
  4.         <add name="soap" type="Microsoft.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  5.         <add name="JSON" type="Microsoft.ServiceModel.DomainServices.Hosting.JsonEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" transmitMetadata="true" />
  6.       </endpoints>
  7.     </domainServices>
  8.     <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  9.   </system.serviceModel>

Suppose we're now done with the configuration of our model using - let's say - Entity Framework and that there is a very simple class in our model called Family that consists of jus two members: ID (Guid) and Name (String). Enrich it with the forenamed metadata:

Family partial class:
  1. [MetadataType(typeof(FamilyMetadata))]
  2. public partial class Family
  3. {
  4.     public Family()
  5.     {
  6.         this._ID = Guid.NewGuid();
  7.     }
  8. }
  9.  
  10. [DisplayColumn("Name")]
  11. sealed class FamilyMetadata
  12. {
  13.     [Key]
  14.     public Guid ID { get; set; }
  15.  
  16.     [Required, StringLength(63)]
  17.     public string Name { get; set; }
  18. }

Please notice how the Name property is marked to be required and of a maximum length of 63 chars.

Done with it. Let's add the RIAService...

VS 2010

VS 2010

Public url of a RIAService has the following form: http://mysite/Namespace-SubNamespace-ClassName.svc (the dots in any namespace toward the classname are changed into a hyphen).
The code generator adds methods for data writing and retrieving that we now omit.

Straight to the point: javascript code!
Now it's all set, here is the html markup for our sample:

Html:
  1. <script src="Scripts/jquery-1.6.2.min.js" type="text/javascript"></script>
  2. <script src="Scripts/jquery.tmpl.min.js" type="text/javascript"></script>
  3. <script src="Scripts/jquery.datalink.js" type="text/javascript"></script>
  4. <script src="Scripts/jquery.validate.min.js" type="text/javascript"></script>
  5. <script src="Scripts/jquery.observable.js" type="text/javascript"></script>
  6. <script src="Scripts/jquery.datasource.js" type="text/javascript"></script>
  7. <script src="Scripts/DomainServiceProxy.js" type="text/javascript"></script>
  8. <script src="Scripts/EntitySet.js" type="text/javascript"></script>
  9. <script src="Scripts/DataContext.js" type="text/javascript"></script>
  10. <script src="Scripts/DataSource.js" type="text/javascript"></script>
  11. <script src="Scripts/LocalDataSource.js" type="text/javascript"></script>
  12. <script src="Scripts/RemoteDataSource.js" type="text/javascript"></script>
  13. <script src="Scripts/AssociatedEntitiesDataSource.js" type="text/javascript"></script>
  14.  
  15. <script type="text/javascript">
  16.     $(function () {
  17.         var svcUri = 'http://gauss/pacem_housesystem/Services/Pacem-HouseSystem-Services-HouseSystemRIAService.svc';
  18.         var render = function (families) {
  19.             var family = families[0];
  20.             $("form input[name='Name']").val(family.Name);
  21.             // track changes at UI level
  22.             $("form").link(family)
  23.             // get validation policies and revert 'em into the layout
  24.             .validate({ rules: ds.getEntityValidationRules().rules });
  25.             //
  26.             $(family).bind("changeField", function (args, field, value) {
  27.                 if (field === "Name") {
  28.                     $("#familyName").html(value);
  29.                 }
  30.                 // IMPORTANT: track changes at datasource level!
  31.                 $.observable(family).setProperty(field, value);
  32.             });
  33.             //
  34.             $.each(family, function (fieldName, value) {
  35.                 $(family).setField(fieldName, value);
  36.             });
  37.             // handlers on both submit and cancel buttons
  38.             $('#submit').click(function (evt) {
  39.                 evt.stopPropagation();
  40.                 evt.preventDefault();
  41.                 if ($('form').valid()) {
  42.                     ds.commitChanges();
  43.                 }
  44.                 else
  45.                     alert('not valid!');
  46.             });
  47.             $('#cancel').click(function (evt) {
  48.                 evt.stopPropagation();
  49.                 evt.preventDefault();
  50.                 ds.dataContext().revertChanges(family, 'Name');
  51.                 // update layout via datalink (tedious)
  52.                 $(family).setField('Name', family.Name);
  53.             });
  54.             // just a test method
  55.             ds.option("entityStateChange", function () {
  56.                 //alert('entity state changed');
  57.                 $('#changeTracker  b').html("yes");
  58.             });
  59.         };
  60.         var ds = $.dataSource({ serviceUrl: svcUri,
  61.             queryName: "GetFamilySet",// ← default retrieving method generated by the RIAService designer
  62.             bufferChanges: true,// buffer all occurred changes, then commit
  63.             refresh: render
  64.         }).refresh();
  65.     });
  66.  
  67. </script>
  68.         
  69. <input type="text" name="Name" />
  70.  
  71. <div id="familyName">...</div>
  72.  
  73. <div id="changeTracker">has changes: <b></b></div>
  74.  
  75. <input id="submit" type="submit" value="submit" />
  76. <input id="cancel" type="reset" value="cancel" />

Screenshot:

UI screenshot
UI screenshot

Fiddler inspector:

Fiddler

Hope it helped.

Take care. Bye.

Feedbacks

  • Re: RIAServices.jQuery for pure HTML Rich Internet Apps

    Darryl Stratford Tuesday, January 24, 2012 0.00

    I'm impressed with RIA/JS. A big problem for me, however, is that it does not support multi-part keys. Great if all your tables have single keys. I see a lot of "TODO" comments in the code and I hope these will be addressed soon.

feedback
 

Syndicate

Author

Cristian Merighi facebook twitter google+ youtube

Latest articles

Top rated

Archive

Where am I?

Author

Cristian Merighi facebook twitter google+ youtube

I'm now reading

Feeds