Могу ли я вернуть JSON из веб-службы .asmx, если ContentType не является JSON? - PullRequest
4 голосов
/ 19 апреля 2010

Я хотел бы опубликовать форму, используя ajax и jquery, для веб-службы .asmx и вернуть значение из веб-службы в виде JSON.

Я использую ASP.NET 4.0. Я знаю, что для возврата JSON из веб-сервиса необходимо установить следующее (1) dataType: "json" (2) contentType: "application / json; charset = utf-8", (3) тип: "POST" (4) установить данные на что-то. Я проверил это, и он работает нормально (то есть мой веб-сервис возвращает данные в формате JSON) , если все ** четыре установлены **.

Но, допустим, в моем случае я хочу сделать стандартную форму сообщения, т.е. test1 = value1 & test2 = value2 поэтому contentType не является JSON, но я хочу вернуть JSON {test1: value1}. Это, похоже, не работает, потому что contentType имеет вид " application / x-www-form-urlencoded " not " application / json; charset = utf-8 ".

Может кто-нибудь сказать мне, почему я не могу этого сделать? Мне кажется сумасшедшим, что вы должны явно отправьте JSON, чтобы получить обратно JSON, но если вы не используете JSON (то есть, публикуете urlencoded contenttype), тогда веб-служба вернет XML.

Любые идеи очень приветствуются:)

Ответы [ 3 ]

7 голосов
/ 20 апреля 2010

Если вы будете использовать WFC RESTfull Service вместо .asmx webservice, вы можете выполнить все свои требования из своего вопроса. Но использование .asmx webservice с JSON в качестве вывода требует , что вы используете как минимум contentType: 'application/json'. В разных местах вы можете найти причину - причину безопасности (см. JSON Hijacking).

Вероятно, x-www-form-urlencoded не является вашей реальной проблемой. Если вы используете dataType: "json", параметры также будут отправлены в форме "test1 = value1 & test2 = value2" !!! Разница лишь в том, что все значения должны быть в кодировке JSON. И jQuery не делает JSON-кодирование данных . (Вы можете посмотреть в коде jQuery.) Основное отличие состоит только в том, что в заголовке запроса будет явно указано «Accept: application / json».

Посмотрите на Ajax-вызов JQuery для httpget webmethod (c #) не работает , который я недавно написал. В этом посте был задан пример запроса GET. Но это почти то же самое. Разница лишь в том, что данные после кодирования будут добавлены к URL (для запроса GET). Для запроса POST данные будут отправлены в теле. Кстати, если установить «processData: false» (см. http://api.jquery.com/jQuery.ajax/), данные GET также будут отправлены внутри тела. Так что прочитайте мой пример кода из AJAX-вызова JQuery для httpget webmethod (c #) не работает . Я надеюсь, что вы получите идеи, как вы можете реализовать то, что вы будете.

Я думаю, у вас были проблемы с кодированием сложных данных для вашего вызова веб-службы .asmx. Вот пример со «сложными» данными:

[WebMethod]
[ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public OutputData AjaxGetMore (InputData input) {
    return new OutputData () {
        id = input.id,
        message = new List { "it's work!", "OK!" },
        myInt = new int[] { input.myInt[0] + 1, input.myInt[1] + 1, 20, 75 },
        myComplexData = new InternalData () { blaBla = "haha", iii = new int[] { 1, 2, 3, 4, 5 } }
    };
}

, где

public class InternalData {
    public string blaBla { get; set; }
    public int[] iii { get; set; }
}
public class OutputData {
    public string id { get; set; }
    public List message { get; set; }
    public int[] myInt { get; set; }
    public InternalData myComplexData { get; set; }
}
public class InputData {
    public string id { get; set; }
    public int[] myInt { get; set; }
    public InternalData data { get; set; }
}

и на стороне клиента

var myData = { id: "li1234", myInt: [100, 200], data : {blaBla: "Hahhh!", iii: [10,20,30]}}
var myDataForjQuery = {input:$.toJSON(myData)};
$.ajax({
    type: "GET",
    url: "/Service1.asmx/AjaxGetMore", // + idAsJson,
    data: myDataForjQuery, // idAsJson, //myData,
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(msg) {
        // var msg = {__type: "Testportal.outputData", id: "li1234", message: "it's work!", myInt:101}
        alert("message=" + msg.d.message + ", id=" + msg.d.id + ", myInt=" + msg.d.myInt); 
    },
    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);
        }
    }
});

($.toJSON взято из плагина JSON) Вы можете изменить этот пример на HTTP POST, если хотите.

Еще один маленький совет. Если вы используете jQuery 1.4.x, вы можете попробовать использовать none в качестве dataType. См. Документацию: «Если ничего не указано, jQuery будет интеллектуально пытаться получить результаты, основываясь на типе ответа MIME (тип XML MIME даст XML, в 1.4 JSON выдаст объект JavaScript, в 1.4 скрипт выполнит скрипт, и все остальное будет возвращено в виде строки) "

С наилучшими пожеланиями

1 голос
/ 19 апреля 2010

Вы также должны установить contentType в запросе JSON. Это позволит вам не указывать в запросе application / x-www-form-urlencoded. Вместо этого вы получите желаемое: application / json; кодировка = UTF-8.

$.ajax({
    url: '/your/site',
    contentType: 'application/json',
    dataType: 'json',
    data: jsonString,
    type: 'post',
    success: function (data) {
        /* do stuff */
    }
});
1 голос
/ 19 апреля 2010

Заголовки запросов и ответов - разные уровни.Таким образом, нет необходимости отправлять конкретный тип данных для его получения.

В случае jQuery просто используйте лежащую в основе функцию .ajax() с dataType, установленным в 'json'.Остальное зависит от вашего вызывающего скрипта / сервиса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...