WCF RIA Services, jQuery, and JSON endpoint – Part 2

In order to perform CUD operations with WCF RIA Services a changeset must be built. All of the operations use JSON/SubmitChanges. What is performed on the entity depends on the Operation enum.

Lets look at the Insert first:

function Insert() {
    var changeSet = [];
    var entityChange = {};
    //Setting Id for entityChange, not the entity key but how the changeset tracks each change
    entityChange.Id = 0;
    entityChange.Entity = { '__type': "PocoEntity:#jQueryDemo.Web", 'EntityKey': 4, 'EntityData': 'Entity 4 Client Data' };
    //Set the type of Operation to be performed on the Entity
    //2 - insert
    //3 - update
    //4 - delete
    entityChange.Operation = 2;
    changeSet.push(entityChange);
    var changsetPayload = JSON.stringify({ "changeSet": changeSet });
    //Create jQuery ajax request
    var Params = {};
    Params.type = "POST";
    Params.url = 'jQueryDemo-Web-PocoDomainService.svc/JSON/' + 'SubmitChanges';
    Params.dataType = "json";
    Params.data = changsetPayload;
    Params.contentType = "application/json"
    Params.success = function (data) {
        for (i in data.SubmitChangesResult) {
            result = data.SubmitChangesResult[i];
            $('body').append('<p>' + result.Entity.EntityData + '</p>');
        }
    }
    //Make the ajax request
    $.ajax(Params);
}
//JSON result from server after submit
{ "SubmitChangesResult": [{
    "Entity": { "__type": "PocoEntity:#jQueryDemo.Web",
        "EntityData": "Entity 4 Client Data",
        "EntityKey": "4"
    },
    "EntityActions": null,
    "HasMemberChanges": false,
    "Id": 0,
    "Operation": 2
}]
}

A changeset is an array of entity changes which have their own id, operation and entity to be modified. Here is the JSON:

{"changeSet":[    
    {"Id":0,     
    "Entity":{
        "__type":"PocoEntity:#jQueryDemo.Web",
        "EntityKey":4,
        "EntityData":"Entity 4 Client Data"},
     "Operation":2}
]}

The Id should be incremented for each operation if there are multiple in the submit. The Entity is the fields to insert plus a special __type string. (Special note: make sure you have two underscores before type or the serializer will not treat it as a special instruction). The format is <type>:#<namespace>. The Operation value lets WCF RIA Services know what to do with the entity. The result on success passes back the entity that the server has. For example if there is an auto-increment database key the client will be able to update its copy of the entity.

Delete is almost identical to Insert with Operation set to 4 instead. I also perform a Load after the delete to refresh the page (rather than find the entity in html and removing that node). To keep things simple I have created a Submit function that handles all CUD operations.

function Delete() {
    var changeSet = [];
    var entityChange = {};
    entityChange.Id = 0;
    entityChange.Entity = { '__type': "PocoEntity:#jQueryDemo.Web", 'EntityKey': 2 };
    //Delete
    entityChange.Operation = 4;
    changeSet.push(entityChange);
    var changsetPayload = JSON.stringify({ "changeSet": changeSet });
    //Create jQuery ajax request
    var Params = {}
    Params.type = "POST";
    Params.url = 'jQueryDemo-Web-PocoDomainService.svc/JSON/' + 'SubmitChanges';
    Params.dataType = "json";
    Params.data = changsetPayload;
    Params.contentType = "application/json"
    Params.success = function (data) {
        Load();
    }
    //Make the ajax request
    $.ajax(Params);
}
//JSON result from server after submit
{ "SubmitChangesResult": [{
    "Entity": {
        "__type": "PocoEntity:#jQueryDemo.Web",
        "EntityData": null,
        "EntityKey": "2"
    },
    "EntityActions": null,
    "HasMemberChanges": false,
    "Id": 0,
    "Operation": 4
}]
}

Update requires an OriginalEntity object with the key and any required fields.

function Update() {
    var changeSet = [];
    var entityChange = {};
    entityChange.Id = 0;
    entityChange.Entity = { '__type': "PocoEntity:#jQueryDemo.Web", 'EntityKey': 3, 'EntityData': 'Entity 3 Client Updated' };
    //Update
    entityChange.Operation = 3;
    //Which entity is being updated. Only has to contain required parameters and keys.
    entityChange.OriginalEntity = { '__type': "PocoEntity:#jQueryDemo.Web", 'EntityKey': 3 };
    changeSet.push(entityChange);
    var changsetPayload = JSON.stringify({ "changeSet": changeSet });
    //Create jQuery ajax request
    var Params = {}
    Params.type = "POST";
    Params.url = 'jQueryDemo-Web-PocoDomainService.svc/JSON/' + 'SubmitChanges';
    Params.dataType = "json";
    Params.data = changsetPayload;
    Params.contentType = "application/json"
    Params.success = function (data) {
        Load();
    }
    //Make the ajax request
    $.ajax(Params);
}
//JSON result from server after submit
{ "SubmitChangesResult": [{
    "Entity": {
        "__type": "PocoEntity:#jQueryDemo.Web",
        "EntityData": "Entity 3 Client Updated",
        "EntityKey": "3"
    },
    "EntityActions": null,
    "HasMemberChanges": true,
    "Id": 0,
    "Operation": 3
}]
}

To improve the sample project I also included an Invoke method that resets the in memory ‘database’. To allow the method to be called with GET, HasSideEffects must be set to false for the Invoke attribute.

$.get('jQueryDemo-Web-PocoDomainService.svc/JSON/ResetData', Load);

The request passes the Load method as a callback so it refreshes the pages data on completion.