Я понимаю, что вы задали очень хороший вопрос. Я люблю и использую XML и XML-схему уже много лет. С полугода я использую JavaScript и jQuery вместе со службами RESTfull WFC, технологиями ASP.NET MVC с данными в кодировке JSON для передачи. Поэтому мне пришлось задать мне тот же вопрос некоторое время назад. Вот мой ответ с кратким объяснением.
XML-структура, которую вы определяете, может представлять один входной параметр нашей веб-службы. Если вы предпочитаете разделять структуру XML на разные входные параметры (например, Locale, Layout и Query), все, что я здесь напишу, может быть легко модифицировано для этого случая кодирования параметров.
На мой взгляд, наиболее естественным является способ, которым мы реализуем с использованием готовых инструментов . Итак, позвольте нам иметь наш веб-сервис с методом, подобным MyMethod
, и входным параметром param
1 с типом MyData
(что-то вроде 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-кодировки:
{ "локаль": "ан", "макет": [{ "ID": "заголовок", "значение": "шкурку"}, { "ID": "колонтитул", "значение": "скрыть "}, {" ID ":" навигация», "значение": "минимизировать"}], "запрос": { "что": "вода", "когда": { "Start": { "Год": 2010 , "месяц": 1, "День": 1}}}
Эти данные являются объектом JavaScript в кодировке JSON
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}
}
}
};
ЗАМЕЧАНИЕ : Поскольку класс JavaScript Date
может быть сериализован несколькими различными способами, я немного изменил представление даты начала здесь. В «мире Microsoft» мы можем использовать Sys.Serialization.JavaScriptSerializer.serialize
для сериализации DateTime
.NET типа, который будет кодировать 2010-01-01 как "/Date(1262300400000)/".
Мы можем написать на C # простой веб-метод Web Service 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);
}
}
});
Для кодирования JSON я использую в примере json2.js (см. 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, вы можете получить более гибкое решение.
Если вы используете 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). Эта проблема может быть решена (или значительно уменьшена) различными способами и это не мешает мне использовать JSON в HTTP-запросах, которые могут быть идеально кэшированы.
Для получения дополнительной информации по той же теме вы можете просмотреть мой ответ на закрытые вопросы:
Как создать объект JSON для отправки в AJAX WebService?
Можно ли вернуть JSON из веб-службы .asmx, если ContentType не является JSON?
JQuery AJAX-вызов веб-метода httpget (c #) не работает