Friday, November 16, 2007

How To : Send Ext datastore to .Net dataset with XML

There are many examples of using the Ext xmlreader to get data xml data into a datastore on the client, however I wanted to do the reverse and allow my CRUD application to update the modified datastore back to the server, updated with user changes.

On the client I created a 'serialize' function to convert the datastore to XML, and then did an Ext.data.Connection to post the data to the server.

SaveDStoServer :function(ds) {

var prog = Ext.MessageBox.wait("Saving data to server");

var ds_serialized= myscope.SerializeDS(ds);

var serv= new Ext.data.Connection();
serv.request({
url: "Service.asmx/Savedata",
params: {myID: 123, datastore:ds_serialized},
method: 'POST',
scope: this,
callback: function(options, success, response){
prog.hide();
if (success){
var xml = response.responseXML;
}
else {
if( response.status == -1 )
Ext.MessageBox.alert('Error on save','Server timeout')
else
Ext.MessageBox.alert('Error on save',response.responseText)
}
}
});
},



SerializeDS : function (ds) {

var columns = ds.fields.keys; // get columns from data store
var retdata ="&ltNewDataSet>";

ds.each ( function (rec) {
retdata +="&lt/datarow>";
for (var i=0; i< columns.length; ++ i)
retdata += "<" + columns[i] + ">" + rec.data[columns[i]]
+ "&lt/" + columns[i] + ">"
retdata += "&lt/datarow>";
});

retdata += "&lt/NewDataSet>";

return ""+retdata;
},
},


On the server side web service method, I create an XML document, create a reader and then read into the dataset. I tried using 'XMLdatadocument' but if did not seem able to create a schema and had an empty dataset. This may not be the most efficient way but it seems to work well. As always, be aware of web service parameter verification to prevent SQL injection.

[WebMethod]
public String Savedata (String SchID, String datastore)
{

DataSet ds = new DataSet();
XmlDocument doc = new XmlDocument();

// Load the xml into an XmlDocument
doc.LoadXml(datastore);
StringReader sreader = new StringReader(doc.DocumentElement.OuterXml);

ds.ReadXml(sreader);

foreach (DataRow row in dsCraft.Tables[0].Rows)
{
System.Diagnostics.Debug.WriteLine(row[0] + " " + row[1]);
}

return "success";
}