>

Client/Server Synchronization & Changes Tracking

Server controls send their updates to the server through standard form submits, or ajax posts that are processed by the Asp.net Mvc Model Binder. Only the TrackedServerGrid has native changes-tracking capabilities, but all other server controls may be equipped with changes tracking with the use of the TrackedListRendering, and ExtTrackedListRendering HtmlHelper extensions. When server controls changes tracking is on it is enough to call the GetChanges IEnumerable<T> extension on the list received by the controller to get the list of inserted, deleted, and modified items. 

If the client side ViewModel used by client controls has been rendered inside an Html Form, when the form is submitted it is automatically sent to the server, deserialized and inserted in the right place in the overall server side viewmodel. Accordingly, clients controls may use exactly the same techniques of server controls to send updates to the server, and they may be equipped with changes tracking capabilities, too,  using the TrackedListRendering, and ExtTrackedListRendering Html Extensions.

However client controls have also the option of sending updates to the server in jSon format. In which case updatesManagers may takes care both of the overall communication protocol and of changes tracking. Each updatesManager computes the change set of the collection it manages, and inserts it in the json model to be sent to the server. Then, it takes care, of dispatching both all principal keys of the newly inserted items, and all errors returned by the server to their right places. The jSon model with all change sets is sent to the server by a single master updatesManager.

updatesManager may be declared with the fluent interface of each client control:

.CreateUpdatesManager("UM")//property where to put the updatesManager
    .BasicInfos(m => m.Id)//entities principal key
    .IsRoot(Url.HttpRouteUrl("DefaultApi"//controller Url
        new { httproute = "", controller = "GridsDemoApi" }))
.EndUpdatesManager()

On the controller side the ResponseBuilder class takes care of building the appropriated response quite automatically:

public HttpResponseMessage Post(OpenUpdater<HumanResourceGuid?> model)
{
    var builder = ApiResponseBuilder
                .NewResponseBuilder(model, ModelState, true
                    "Error in client request");
    if (ModelState.IsValid)
    {
        try
        {
            builder.Process(m => m, m => m.Id);
            //call to business layer here!
            fakeDB.Insert(model.Inserted); 
            fakeDB.Delete(model.Deleted); 
            fakeDB.Modify(model.Modified);       
            // end business layer processing
        }
        catch (Exception ex)
        {
            ModelState.AddModelError("", ex.Message);
            return
                Request.CreateResponse(
                    System.Net.HttpStatusCode.InternalServerError,
                    new ApiServerErrors(ModelState));
        }
    }
    return builder.GetResponse().Wrap(this.Request);
}

Anagously, javascript viewModelUpdatesManagers send generic objects to the server, and take care of dispatching all errors possibly returned by the server to their right places in the UI (i.e next to the appropriate input fields). Also in this case the ResponseBuilder class takes care of extracting all errors from the ModelState.

The ResponseBuilder may change the client side ViewModel either by returning an object that may be processed in the onUpdateComplete function of the updatesManager / viewModelUpdatesManager, or by returning remote commands that modify automatically the client side ViewModel. Remote commands are recorded on the server side and executed on the client side. They enable the developer to modify the client side ViewModel without substituting it. In fact, often a complete substitution is not possible because it would  break all connections the ViewModel has with UI elements and other data structures.

The Data Moving Plug-in offers also tools to handle complex Single Page Applications. In complex applications typically just a a part of the overall client-side ViewModel is sent to the server. We call Workspaces, the sub-parts of the Client-side ViewModel that are sent to the server together in a single “batch”. A Workspace, in turn, is composed of two conceptually different sub-parts: a kind of short living data structure that is used just to carry out the current task and a set of long living data structures that are typically connected with a Database on the server side. Typically, on the client side, we don’t have all long living entities  of a “given type” but just a small window of the whole Entity Set. We call Entity Set Window, a set of all long-living entities of the same type stored in the client side ViewModel, and we call Core Workspace the part of the Workspace that remains after removing all Entity Set Windows.

UpdatesManagers take care each of a different Entity Set Window, and each Workspace may have also a viewModelUpdatesManger that handles the synchronization of the Core Workspace. The viewModelUpdatesManger  acts as a manager and coordinates the whole update process, quite automatically:  a single call the update method of the viewModelUpdatesManger instance triggers the whole operation of preparing the Workspace and sending it to the server with a single ajax call. The viewModelUpdatesManger issues all appropriate commands to all updatesManagers of the Entity Set Windows  contained in the Workspace, and when all data to be sent to the server are ready, and if there are no client side validation errors, it starts the communication with the server. Also in this more complex case, on the server side, the responseBuilder class takes care of building the appropriated response quite automatically. It extracts also all long living entities contained in the Core Workspace and place them in the inserted or modified collections of the entity set they belong to.

More details on Client/Server synchronization in complex SPA applications may be found in this tutorial. The code associated to the tutorial is available on codeplex.