Веб-метод ASMX, получающий неэкранированную двойную кавычку в параметре, JSON - PullRequest
3 голосов
/ 26 января 2012

Мой запрос HTTP содержит допустимую строку JSON с двойной кавычкой в ​​середине имени "jo \" hn ", экранированную, как показано здесь (захвачено Fiddler Web Debugger)

{"name":"firstName","value":"jo\"hn"},

Примечание:Процесс отправки запроса использует стандартный jQuery $.ajax(..) call , как показано в этой статье без проблем.


Проблема на стороне сервера

Мой метод веб-службы C # ASMX получаетследующее строковое значение C # со средней двойной кавычкой неэкранировано (т. е. обратный слеш удален). Его нельзя десериализовать, не вызвав ошибку, показанную ниже.

Это место, где происходит дизъюнкт в процессе, прежде чем я получузначение в мой веб-метод. Это как если бы ASP.NET обрабатывал строку внутренне, удаляя ее и удаляя ее обратно без экранирования, изменяя исходное значение, а не дословно предоставляя его параметру веб-метода.

C # String is:

{"name":"firstName","value":"jo"hn"},

Веб-метод ASMX примерно такой:

using System.Web.Script.Serialization;
using System.Web.Script.Services;

[WebMethod]
[ScriptMethod(ResponseFormat = System.Web.Script.Services.ResponseFormat.Json)]
public string saveData(string values)
{
    JavaScriptSerializer json = new JavaScriptSerializer();
    request = json.Deserialize<List<NameValuePair>>(values.ToString());
                // ^^^ KABOOM! 

ИсключениеПонятно, что n сообщение:

{"Введен неверный объект, ожидается ':' или '}'. (423): [{\" name \ ": \"плс $ л $ zoneHeaderTopNav $ searchBoxTopNav $ txtWord \», \ "значение \": \ "\"}, {\ "имя \": \ "приветствием \", \ "значение \": \ "г \"},{\ "имя \": \ "Firstname \", \ "значение \": \ "Джох \" п \ "}, {\" имя \ ": \" LastName \ "\ "значение \": \"кузнец \ "}, {\" name \ ": \" initial \ ", \" value \ ": \" d \ "}]"}

Как лучше всего решить эту проблемупроблема, не переходя от классических веб-сервисов ASMX?

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

Однако мне интересно, есть ли простой ответ: настроить конфигурацию, использовать атрибут, настройку или метод перегрузки, которые могут решить проблему?

Я немного потрудился в Интернете, но большинство статей посвящено возврату данных JSON с сервера на клиент и решению проблем в этой области.


Примечание к приложению : полная информация о вызове на стороне клиента, запрошенная Дарин Димитров

ОБНОВЛЕНИЕ: ответ Дарина размещен здесь, встроенный, для простотыссылка

function SaveDraft() {

    $.checklist.checkvalid();
    var formObj = $(':input:not([type=hidden])').serializeArray();

    var request = JSON.stringify(formObj);
    request = request.replace(/'/g, "");

    $.ajax({
        url: "/Service.asmx/saveData",
        type: "POST",

        // *** Original erroneous line: uses string concat - commented out
        // data: "{'values':'" + request + "'}",

        // *** CORRECTED LINE: provides an object instead of a string and calls JSON stringify.
        data: JSON.stringify({ values: request }), 

        dataType: "json",
        contentType: "application/json; charset=utf-8",
        success: SaveDraftSuccess,
        error: SaveDraftFail
    });
}

Примечание. Это вариант вызова, который создает действительный фрагмент JSON, показанный в верхней части вопроса.

1 Ответ

3 голосов
/ 26 января 2012

Почему вы делаете эту ужасную ручную десериализацию JSON в вашем веб-сервисе? Позвольте мне предложить вам гораздо лучший подход.

Начните с определения модели:

public class Person
{
    public string Name { get; set; }
    public string Value { get; set; }
}

затем веб-метод:

[WebMethod]
[ScriptMethod]
public string SaveData(Person person)
{
    ...
}

и тогда вы можете вызвать его из JavaScript. Например, используя jQuery:

$.ajax({
    url: 'foo.asmx/SaveData',
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify({
        person: {
            name: 'firstName',
            value: ' jo\"h\'n'
        }
    }),
    success: function(result) {
        alert(result.d);
    }
});

Никаких кабумов.

Метод JSON.stringify, показанный здесь, является встроенным в современные браузеры, но если вам нужно поддерживать устаревшие браузеры, вы можете добавить на свою страницу скрипт json2.js .


ОБНОВЛЕНИЕ:

Теперь, когда вы показали свой код, кажется, что вы не кодируете свой запрос. Попробуйте вот так:

var formObj = $(':input:not([type=hidden])').serializeArray();
var request = JSON.stringify(formObj);
$.ajax({
    url: "/Service.asmx/saveData",
    type: "POST",
    data: JSON.stringify({ values: request }),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: SaveDraftSuccess,
    error: SaveDraftFail
});

На что следует обратить внимание: вам не нужны регулярные выражения для удаления одинарных кавычек, и вы должны использовать JSON.stringify для правильного кодирования значений вашего запроса.

...