Monday, 6 August 2012

2. Silverlight + RIA Services – Services

What tooling is doing – LinqToEntitiesDomainService<T> based on Entity Framework model derived from DomainService where T is our LINQ to Entities ObjectContext.
Now let’s dig into this - DomainService is an abstract class with no abstract methods but lots of things to override;
Note - Sometimes you don't want to give the possibility to instantiate a class but you need this class as a base class for other classes. So we can have abstract class without any abstract method.



There’s quite a lot of functionality in there relating to ChangeSets such as;

ChangeSet property 
AuthorizeChangeSet() 
ExecuteChangeSet() 
PersistChangeSet() 
Submit() 
ValidateChangeSet() 
There’s functionality that looks to relate to querying such as;

Query() 
Count() 

and then there’s the notion of “invoking” something;

Invoke() 

and then some additional pieces around all of this like;

Initialize() 
OnError() 
and various pieces of contextual information such as ServiceContext, ServiceDescription, ValidationContext, AuthorizationContext 

and so there’s quite a lot in this one class.

If I create DomainService like my ExampleDomainService here; We get the following DomainService


 along with the necessary references ( System.ServiceModel.DomainServices.* at least ) to make this build. In my web.config file I also noticed that a module is added to the pipeline – DomainServiceHttpModule - and ASP.NET compatibility is turned on for System.ServiceModel.

So, what’s the role of the DomainServiceHttpModule? It uses a VirtualPathProvider in order to dynamically make available service(s) that it constructs from DomainService derived types that it finds in the referenced assemblies of the application.

You can see this ( if you’re following along ) by visiting the equivalent of;
http://[VROOT]/Services/WebApplication1-ExampleDomainService.svc

where VROOT for me was localhost:27544 because I was serving up my web application project via Cassini on port 27544.

That SVC file is dynamically generated rather than being something that has to physically exist in the project and the dynamically generated SVC file ends up looking something like;

<%@ ServiceHost Factory=”DomainServiceHostFactory” Service=”ExampleDomainService” %>

and so this factory is used to bring in a custom service host for WCF ( DomainServiceHost ).

The DomainServiceHost knows how to perform a few tricks including;
1. Generate a service description for WCF from your DomainService 
2. Generate a set of endpoints for WCF from your DomainService 

In terms of the service description, the built-in way that this happens is by reflecting over your DomainService class looking for particular kinds of operations exposed publicly from that class. The set of operations that are looked for and the shape that they need to have are listed up here but the basic idea is that the framework code is looking for;

Query operations 
Insert operations 
Update operations ( these fall into 2 categories of “Update” or “Custom” ) 
Delete operations 
Invoke operations 

and then building a service description based upon what it finds. 

In terms of the endpoints, the DomainServiceHost makes available a default endpoint over HTTP (or HTTPS) using a binary encoding and it also adds in an authentication scheme based on what it sees being used by the default webHttpBinding that you have configured. That is – as an example, if webHttpBinding is using “Windows” authentication by default then the default endpoint will do the same.

My request for WebApplication1-ExampleDomainService.svc above was met with an error;
“ContractDescription 'ExampleDomainService' has zero operations; a contract must have at least one operation.”
which makes sense in that my DomainService has no functionality available on it. 

The simplest thing I could do is to add an operation to it and the simplest kind of operation that I can add is an Invoke operation because those are closest to standard WCF service operations in that they are calls from client to service that are simply executed ( asynchronously ).

I could add an “Invoke” operation;



and then my service no longer complains when I visit its URL at WebApplication1-ExampleDomainService.svc;




Now – I can’t get WSDL for this endpoint even though there’s a link there. That’s not the intention for this default endpoint.

This default endpoint is for easy access from a WCF RIA Services client. It’s possible to expose other endpoints for access from other clients ( I’ll return to this ) but this endpoint is the default one and is targeted at easy, efficient calling from a WCF RIA Services client.
On the client-side the generation process will make a corresponding ExampleDomainContext class that knows how to “talk” back to my service with public members on that class that cause the invocation of my Add method server side. That means that I can write code such as ;



and that all works fine and calls my service-side operation for me without any additional steps.
It’s interesting to note what kinds of interaction this call from the client drives with my ExampleDomainService class on the service-side here. If I were to override the methods Initialize() and Invoke() then I’d see them being called as these pictures from the debugger shows;




you can see that I’m authenticated ( interesting! I’ll return to this ) and that the operation type is an Invoke. We next arrive in my override of the Invoke method;


which is being called with the method that the client side wants to invoke and the parameters for that method. Then my actual Add method would be invoked, the return value gathered and sent back to the client. So, the DomainService has a sort of “life cycle” for handling client-side calls and here the invocations coming from the client cause the service-side code to go through a cycle of Initialize->Invoke->MyMethod.

Now, whilst this ease of calling without an explicit service reference has some advantages over just using raw WCF it’s more likely that we’d want to expose sets of entities for the client to operate on and we see a lot more benefit in doing that. So, if I have an entity such as; it feels like I should be able to write a method that matches the pattern for a query operation such as;



but that won’t work even with my made up test entities being returned. The framework needs an entity to have a Key defined to tell it how to identify an instance ( not unreasonable ) and so I might do; and then make sure that the Key is set up ( notice that I keep returning the same keys here for repeat invocations );


and then I can query against that from the client side – for example;




It’s kind of interesting to see what flows across from client to service in this instance – taken from Fiddler;


where we can see that the request was encoded into the query string and the response;



was binary encoded but the important point is around the client’s automatic ability to communicate with the service – not the particular protocols that it uses to do it.
It’s also interesting to see the invocations made onto the DomainService and, once again, if I override a few methods and use the debugger I can see that when the client runs a query I see a call to Initialize() on the newly constructed DomainService and then;



a call arrives into the Query method and you can see that the Method is specified and the Query is specified and IncludeTotalCount is specified – it’s all come into the call.
Then the base class implementation here will take that and route it to my method GetPeople() to actually get the data that is then used as the basis of the query which can then be executed and the results returned to the client. What about if we want to modify data? At the moment, my ExampleDomainService doesn’t support the idea but I could add a few empty methods to it to at least give the impression that it can support modifications;



Ok, so now when I rebuild I see a change on the client side.
Previously, I noticed that the DomainContext on the client side has a generated override called CreateEntityContainer and in my case this is creating an instance of a generated class called ExampleDomainEntityContainer.
Now, prior to my addition of those 3 new methods service-side that class looked like;


but after the additions I now see;



and so that EntityContainer is allowing modifications to my Person entity set so I can write code on the client side that attempts inserts/updates/deletes such as;


where we are doing a single delete, a single update and a single insert. Note that nothing crosses the client/service barrier until we hit the SubmitChanges call on line 19 above. At that point, we see the service-side ExampleDomainService get instantiated and then its Initialize() method is called as we’ve come to expect. From there, the calls are;



and so you can see that we get a call to Submit() and what’s been sent from the client side is a ChangeSet and the debugger clearly shows that the ChangeSet contains one insert, one update, one delete. So, the methods that we’ve written ( InsertCustomer, UpdateCustomer, DeleteCustomer ) are not “directly” called from the client side but, instead, are routed through Update which drives a “life cycle” of method calls - next we see a call to AuthorizeChangeSet;




and you can see that the ChangeSet in progress is represented in this.ChangeSet for access. There’s also the AuthorizationContext property which is null in this case ( more on that in a later post ).From there, we move to ValidateChangeSet;



and from there to;



and then the base class implementation causes my InsertPerson, UpdatePerson, DeletePerson methods to be called to do their work before making these changes final by calling;


so there’s a whole set of interactions driven by the arrival of our ChangeSet into the Submit method on our ExampleDomainService and the DomainService is really offering three things here as service operations;

Query 
Invoke 
Submit 

There’s another aspect to Update in that there’s a notion of a named update operation. If I was to add a named update operation to my service such as;


then that can be called on the client side via one of two mechanisms – it shows up on the generated ExampleDomainContext as you’d expect but it also shows up as an instance 
method on the generated Person entity on the client side so that I can change my client code to add;


adding that call to OperationOnAPersonWithNoSpecialNamePrefix on lines 17/18 and then the service-side interactions from this are;

ExampleDomainService::ctor 
ExampleDomainService::Initialize() 
ExampleDomainService::Query() 
and that satisfies the query and then for the Submit call we see;
ExampleDomainService::ctor 
ExampleDomainService::Initialize() 
ExampleDomainService::Submit() 
ExampleDomainService::AuthorizeChangeSet() 
ExampleDomainService::ValidateChangeSet() 
ExampleDomainService::ExecuteChangeSet() 
InsertPerson(), UpdatePerson(), DeletePerson() 


and then my named update operation is called;


followed up with a call to ExampleDomainService::PersistChangeSet() at the end of the cycle.
Up until now, my service has only offered the single entity set Person but it’s pretty likely that we’d have related entities in the model that I’d want to expose. Perhaps Person can have a set of addresses.


Note that in order to relate entities, I have the Address.Id property but also the foreign key of Address.PersonId which links back to the “owning” Person entity. There’s also an attribute 
[Association] which I’ll apply to my Person entity which tells the framework which properties to look at in order to determine these key values.

The framework also needs a bit more help in the sense that it needs to know whether the Addresses belonging to a Person are there for server-side programming or to be included 
down on the client-side. This is done via an IncludeAttribute. 

With that said, I can modify my Person entity in order to add the [Include] attribute, the [AssociationAttribute] and to make sure that each Address instance has the right PersonId 
foreign key set on it;


you might also notice one other attribute has crept in – the CompositionAttribute. What’s that for? Well, there’s a very good explanation here but what it’s essentially saying is that (in this model) the Person owns the Address and so (e.g.) removing the Address from the Person means the Address needs to be deleted – it doesn’t exist in its own right.

If I then add some CRUD operations to my ExampleDomainService for my Address entity;


and make sure that my test entities returned from my GetPeople() query are created with the right flag such that they create dummy Address data;


then I can code against it on the client-side – iterating through the Persons/Addresses in the standard manner;


where it’s worth noting that this is one query to the service rather than one for the Persons entity set and then one for each set of Addresses belonging to them ( i.e. Addresses are not being lazily loaded here ).


And I can also do some inserting, updating, deleting from the client side – for example;


and so this is removing 1 address, updating a second address and then adding a new person with a new address. On the service-side when we hit  ExampleDomainContext::ExecuteChangeSet I see calls to my methods;
InsertPerson ( for the new Id = 6 with the Addresses property populated to the created Address on line 12 with Id 61 ) 
InsertAddress for that Address 
UpdatePerson for the Person with Id = 1 which has 2 Addresses attached to it because 1 was deleted client side 
UpdateAddress for the Address which was updated on line 4 above 
DeleteAddress for the Address which was removed on line 3 above 
so my client-side work gets nicely replayed to my service-side and if I had a proper data access layer under these classes then it would do something with my data-store to actually 
make these changes live.


This post has got long but there’s one last thing I wanted to squeeze in. The RIA Services Client<->Service communication is largely automatic and the focus is on getting the functionality built rather than worrying about protocols and so on underpinning it.
However, that doesn’t mean that you can’t access these services from elsewhere and there’s a few ways of doing it. Within the RIA Services framework itself, there’s support for 
offering access over OData and you can do that by altering your configuration file. If I modify my config file to add a custom configuration section for domainServices within system.serviceModel as in;


and then also use that configuration section in order to request an OData endpoint;


then I can visit my service at WebApplication1-ExampleDomainService.svc/odata/ ( notice that trailing slash there because it seems to matter a lot ) and I see;


so – no collections exposed there but in order to expose collections such as my Person data I need to tell the framework which is the default query for that entity type which involves 
changing my ExampleDomainService class; and now when I visit my service I can see;


and I can then navigate into that dataset as in;



but I’m not sure that I can take that further by adding ( e.g. ) additional parts to the query such as indexing into the data by primary key or starting to build up expressions including $top, $skip, $filter, and so on.

An OData endpoint is just an example here though. It’s possible to expose other kinds of endpoints for other kind of clients. There are two more possibilities within the RIA Services Toolkit ( SOAP and JSON ) or you can write your own.
So, to offer up a SOAP endpoint I can dig into my RIA Services Toolkit and change my configuration;

and now I’ve got a SOAP endpoint that I can hit against and if I visit my service for a WSDL file which in my case involves hitting;
http://localhost:27544/WebApplication1-ExampleDomainService.svc?wsdl
then I see WSDL;


and I can go and do an Add Service Reference against that from Visual Studio (or some other IDE or tool) and start to work with my service in that way.

Friday, 27 July 2012

1. Silverlight + RIA Services - Overview

A big part of the Silverlight 4 release is the new WCF RIA Services framework.

Its worth pointing out that WCF RIA Services doesn’t only target Silverlight clients – it also targets AJAX clients but I’m sticking with the Silverlight side of the house here.

Common Silverlight application architecture looks something like this -


Between the two is “the gap” that has to be spanned by some kind of distributed application technology and there are various possibilities in Silverlight such as the following listed in the order in which they are layered on top of each other;

  • Sockets ( both TCP streaming and UDP multicast )
  • HTTP ( via the WebClient and HttpWebRequest classes )
    • This might be achieved by passing backwards and forwards XML and there are various technologies in Silverlight to help with that such as LINQ to XML, XPath, XmlReaders/XmlWriters, XML Serialization, WCF Data Contract Serialization
    • Or you might look to JSON and there are technologies in Silveright for dealing with that such as the “LINQ to JSON” technology and/or the JSON serialization technologies
  • Windows Communication Foundation ( WCF )
    • Via HTTP
      • Built-in support doing text/binary encodings over HTTP(S)
      • Built-in support for authentication via transport mechanisms ( i.e. integrated authentication via basic, digest or NTLM ) and via SOAP mechanisms ( i.e. “transport with message credential” )
    • Via TCP
      • Offering the WCF duplex programming model for binary message transfer albeit without security support

all of these technologies are “data transfer” technologies in that they move some bits from A to B.

It feels relevant to me to note that WCF offers a much higher level of abstraction than (say) raw socket programming in that you generally author services that are described in terms of a service contract and then offered over some binding that builds up the transport, encoding, security options and so on. On the client side you’re typically using metadata offered by the service in order to use tools to build up proxy classes to access the service.

It’s interesting how this combination comes together – with the right framework pieces and the right tools you can get to an abstraction that makes distributed programming far more productive.

On top of the WCF stack there’s also the WCF Data Services stack which offers OData compliant clients and services.

WCF Data Services is very data-centric in that you decide on that data that you want to expose and WCF Data Services exposes that for you in a RESTful manner as a number of AtomPub collections that you can then query into using OData’s URI syntax.

The services that you produce can be pretty much accessed from any platform and any client as you can see by taking a look at the consumers section on the OData website.

Whilst the focus is definitely on the data, WCF Data Services also makes it possible to expose arbitrary server-side operations as additional functionality and to intercept incoming operations and/or queries in order to add business logic but the primary intent is to expose data as the name of the technology suggests.

Silverlight is just one possible client for WCF Data Services and the client library does offer some higher level abilities than basic CRUD over entity sets with capabilities such as;

  • ability to turn LINQ formed queries into URI based syntax compatible with OData
  • automatic tracking of changes made to entities ( and entity sets ) returned from WCF Data Services to make for automatic submission of changes
  • ability to deal with concurrent updates and the errors/retries that are needed to deal with those situations
  • batching of queries/modifications to the server

but the level of shared knowledge ( “coupling” ) between the client and the services is still very low.

Typically, the client developer adds a service reference to a WCF Data Service and the “shared knowledge” between the client and the service is downloaded in the form of the service metadata which describes to the client;

  • the “shape” of the entities that the service exposes
  • the entity sets available
  • the relationship between entities such that those relationships can be navigated

but that’s about the extent of it. There’s nothing shared about ( e.g. ) how to authenticate with the services, how authorisation might be performed by those services, how validation might be performed by the services etc.

There are upsides and downsides to this degree of separation – the potential for a variety of different clients and for independent versioning of the client/service are on the upside and productivity is a likely downside as you deal with the complexity of writing application logic on both the client and server side of the equation and code that shuffles collections of entities backwards and forwards whilst preserving state around whether they’ve been modified or not.

WCF RIA Services bridges “the gap” in a different, higher level way by embracing the idea that the client and the service are part of an application rather than separate clients and services that come together over an agreed contract.

Consequently, in a RIA Services application there is the tooling and framework support for sharing a richer set of artefacts between the client and the service than you’d see with a solution built around something lower level like a pure WCF solution allowing for a lot less friction in terms of;

  • making the service-side data model entities visible to the client side code
  • offering the ability for the client-side code to construct queries ( via LINQ ) which are then serialized, sent to the server for execution with the result-sets then returned to the client including the ability to add sorting, paging into those queries
  • offering automatic tracking of entity changes and entity-set changes on the client side
  • offering easy mechanisms for submitting client-side changes back to the server side and handling possible update failures
  • offering the ability to specify validation constraints and have them applied both client- and service-side
  • offering the ability to share arbitrary code between the client and service
  • offering the ability to easily share ASP.NET services such as membership, roles, profile with a Silverlight client

I want to dig in to WCF RIA Services a little more over future posts but I thought for now it’d be good to start with a “magic demo” which illustrates the sort of speed that WCF RIA Services can give you when combined with Visual Studio 2010.


Tuesday, 26 June 2012

Silverlight Browser Cookies

Cookies are strings of text that the server can store on the client side. These cookies can then be sent back by the client to the server each time the client accesses that server again. Cookies are commonly used for session tracking, authentication, site preferences and maintaining specific information about users. For example, items a client stores in a shopping cart can be stored on the client side as cookies so that they can leave the online store and return later to check out.
So, how do we set cookies from within a Silverlight application? To accomplish this we turn again to the HtmlPage.Document object. To use this object you must add a using statement to reference the System.Windows.Browser namespace.
To set a cookie we need to call SetProperty() with a string in the following format: “Key=Value;expires=ExpireDate.”

For example:

private void SetCookie(string key, string value)
{
// Expire in 7 days
DateTime expireDate = DateTime.Now + TimeSpan.FromDays(7);

string newCookie = key + "=" + value + ";expires=" + expireDate.ToString("R");
HtmlPage.Document.SetProperty("cookie", newCookie);
}

Now, to get the cookie we split up and iterate through all the cookies returned through the property HtmlPage.Document.Cookies.

For example:

private string GetCookie(string key)
{
string[] cookies = HtmlPage.Document.Cookies.Split(';');

foreach (string cookie in cookies)
{
string [] keyValue = cookie.Split('=');
if (keyValue.Length == 2)
{
if(keyValue[0].ToString() == key)
return keyValue[1];
}
}
return null;
}