I understand you question very good. I like and have been using XML and XML schema since many years. Since a half of year I use JavaScript and jQuery together with RESTfull WFC services, ASP.NET MVC technologies with JSON encoded data for transfer. So I had to ask me the same question some time ago. Here is my answer with a short explanation.
The XML structure which you define can represent one input parameter of our Web Service. If you prefer divide XML structure to different input parameters (like Locale, Layout and Query) all what I write here can be easy modified to this case of parameter coding.
The most native way in my opinion is the way which we implement using out-of-the-box tools. So let us we have our Web Service with a method like MyMethod
and an input parameter param
1 with the type MyData
(something like public int MyMethod (MyData param1)
). Class MyData
represent our all data from the XML structure. Then the corresponding HTTP GET request should look like
http://server/Service/MyMethod?param1=JsonEncodedData
where JsonEncodedData:
%7B%22locale%22%3A%22en%22%2C%22layout%22%3A%5B%7B%22id%22%3A%22header%22%2C%22value%22%3A%22hide%22%7D%2C%7B%22id%22%3A%22footer%22%2C%22value%22%3A%22hide%22%7D%2C%7B%22id%22%3A%22navigation%22%2C%22value%
or the same without HTML encoding:
{"locale":"en","layout":[{"id":"header","value":"hide"},{"id":"footer","value":"hide"},{"id":"navigation","value":"minimize"}],"query":{"what":"water","when":{"Start":{"Year":2010,"Month":1,"Day":1}}}
This data is a JSON encoded JavaScript object
var myInput = {
locale: "en",
layout:[
{id: "header", value: "hide"},
{id: "footer", value: "hide"},
{id: "navigation", value: "minimize"}
],
query:{
what: "water",
when: {
Start:{Year:2010,Month:1,Day:1}
}
}
};
REMARK: Because Date
class of JavaScript can be serialized in a little different ways I changed a little the representation of start date here. In the "Microsoft world" we can use Sys.Serialization.JavaScriptSerializer.serialize
to serialize DateTime
.NET type which will encode 2010-01-01 like "\/Date(1262300400000)\/".
We can write in C# an easy Web Method of Web Service Service1.asmx like
[WebMethod]
[ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public int MyMethod (MyData param1) {
return param1.query.when.Start.Year;
}
where
public enum BlockType {
hide,
minimize
}
public class Block {
public string id { get; set; }
//public BlockType value { get; set; }
public string value { get; set; }
}
public class MyDate {
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
}
public class When {
public MyDate Start { get; set; }
}
public class Query {
public string what { get; set; }
public When when { get; set; }
}
public class MyData {
public string locale;
public List<Block> layout;
public Query query;
}
And the corresponding client code will looks like following
var myInput = {
locale: "en",
layout:[
{id: "header", value: "hide"},
{id: "footer", value: "hide"},
{id: "navigation", value: "minimize"}
],
query:{
what: "water",
when: {
Start:{Year:2010,Month:1,Day:1}
}
}
};
$.ajax({
type: "GET",
url: "/Service1.asmx/Method2",
data: {param1: JSON.stringify(myInput)},
contentType: "application/json; charset=utf-8",
success: function(data, textStatus, XMLHttpRequest) {
alert(XMLHttpRequest.responseText);
},
error: function(res, status) {
if (status ==="error") {
// errorMessage can be an object with 3 string properties:
// ExceptionType, Message and StackTrace
var errorMessage = $.parseJSON(res.responseText);
alert(errorMessage.Message);
}
}
});
For JSON encoding I use in the example json2.js (see http://www.json.org/json2.js and http://www.json.org/js.html). One can use instead JSON jQuery (from http://code.google.com/p/jquery-json/), then JSON.stringify
should be replaces to $.toJSON
.
Initializing of data of the type MyData
can look like
new MyData {
locale = "en",
layout = new List<Block> {
new Block() { id="header", value=BlockType.hide.ToString()},
new Block() { id="footer", value=BlockType.hide.ToString()},
new Block() { id="navigation", value=BlockType.minimize.ToString()}
},
query = new Query {
what = "water",
//when = new When() {Start = new DateTime(2010,1,1)}
when = new When () {
Start = new MyDate () {
Year = 2010,
Month = 1,
Day = 1
}
}
}
};
}
If you use WCF with webHttpBinding (RESTfull endpoints) instead of asmx based web services you can receive more flexible solution.
If use use JSON with HTTP GET you should take in consideration existence of the JSON Hijacking problem (see http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx, http://haacked.com/archive/2009/06/25/json-hijacking.aspx). This problem can be solved (or dramatically reduced) in the different ways and it don't stop me from the usage of JSON in HTTP requests, which can be perfect cached.
For more information about the same subject you can look through my answer to a close questions:
http://stackoverflow.com/questions/2737525/how-do-i-build-a-json-object-to-send-to-an-ajax-webservice/2738086#2738086
http://stackoverflow.com/questions/2670147/can-i-return-json-from-an-asmx-web-service-if-the-contenttype-is-not-json/2671583#2671583
http://stackoverflow.com/questions/2651091/jquery-ajax-call-to-httpget-webmethod-c-not-working/2656543#2656543