我明白你的问题很好。我喜欢并且多年来一直在使用 XML 和 XML 模式。半年以来,我使用 JavaScript 和 jQuery 以及 RESTfull WFC 服务、带有 JSON 编码数据的 ASP.NET MVC 技术进行传输。所以前段时间我不得不问我同样的问题。这是我的回答和简短的解释。
您定义的 XML 结构可以代表我们 Web 服务的一个输入参数。如果您更喜欢将 XML 结构划分为不同的输入参数(如 Locale、Layout 和 Query),那么我在这里写的所有内容都可以轻松修改为这种参数编码的情况。
在我看来,最原生的方式是我们使用开箱即用的工具实现的方式。因此,让我们拥有一个带有类似MyMethod 的方法的Web 服务和一个带有MyData 类型的输入参数param1(类似public int MyMethod (MyData param1))。 MyData 类代表我们所有来自 XML 结构的数据。那么对应的 HTTP GET 请求应该是这样的
http://server/Service/MyMethod?param1=JsonEncodedData
在哪里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%
或没有HTML编码的相同:
{"locale":"en","layout":[{"id":"header","value":"hide"},{"id":"footer","value":"hide "},{"id":"navigation","value":"minimize"}],"query":{"what":"water","when":{"Start":{"Year":2010 ,"月":1,"日":1}}}
此数据是 JSON 编码的 JavaScript 对象
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}
}
}
};
备注:因为Date JavaScript 类可以用一些不同的方式序列化,所以我在这里稍微改变了开始日期的表示。在“微软世界”中,我们可以使用Sys.Serialization.JavaScriptSerializer.serialize 序列化DateTime .NET 类型,该类型将编码 2010-01-01,如“/Date(1262300400000)/”。
我们可以用C#写一个简单的Web服务方法Service1.asmx之类的
[WebMethod]
[ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public int MyMethod (MyData param1) {
return param1.query.when.Start.Year;
}
在哪里
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;
}
相应的客户端代码如下所示
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);
}
}
});
对于我在示例 json2.js 中使用的 JSON 编码(参见 https://github.com/douglascrockford/JSON-js/blob/master/json2.js 和 http://www.json.org/js.html)。可以使用 JSON jQuery(来自 http://code.google.com/p/jquery-json/),然后将 JSON.stringify 替换为 $.toJSON。
MyData 类型数据的初始化可能如下所示
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
}
}
}
};
}
如果您将 WCF 与 webHttpBinding(RESTfull 端点)一起使用,而不是基于 asmx 的 Web 服务,您可以获得更灵活的解决方案。
如果将 JSON 与 HTTP GET 一起使用,则应考虑到 JSON 劫持问题的存在(请参阅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)。这个问题可以通过不同的方式解决(或显着减少),它不会阻止我在 HTTP 请求中使用 JSON,它可以完美缓存。
有关同一主题的更多信息,您可以查看我对关闭问题的回答:
How do I build a JSON object to send to an AJAX WebService?
Can I return JSON from an .asmx Web Service if the ContentType is not JSON?
JQuery ajax call to httpget webmethod (c#) not working