Ошибка JSON при отправке в IE7 (и только в IE7): «Невозможно десериализовать. Данные не соответствуют действительному JSON». - PullRequest
0 голосов
/ 14 января 2011

Это строго проблема IE7; IE8 не возражает, как и FF. Наша форма выдает следующее исключение при отправке:

Sys.ArgumentException: Cannot deserialize. The data does not correspond to valid JSON.
Parameter name: data

Форма заголовка (отредактировано для секретности; у нас есть параноик NDA):

<%using (Ajax.BeginForm("...", "...", FormMethod.Post,
    new AjaxOptions {
       OnComplete = "OnSaveEditCommunitySuccess",
       OnBegin = "OnBegin" },
    new { id = "form_Edit...", name = "form_Edit..." }))

Я временно прикрепил обработчик к OnBegin и посмотрел на объект json, который передается вокруг. Я могу гарантировать, что json.get_request().get_body() идентично тому, что происходит в FF, и правильно закодировано в сети:

ProfileTabModel.IsEdit=true&ProfileTabModel.HandEnterCommunity=true&ProfileTabModel.CommunityId=26&ProfileTabModel.County=&ProfileTabModel.OrgId=7395& (...)

Может показаться уместным, что это большая форма, и отправленные данные имеют размер не менее 2500 байтов. Я понимаю, что это не должно иметь значения в POSt, и даже если это так, это не имеет ничего общего с сообщаемой ошибкой, но лучше упомянуть об этом, поскольку другие формы, написанные по тому же шаблону, не имеют проблем с публикацией своих данных.

[EDIT:] При работе в режиме отладки IE7 не вводит действие в контроллер, а все остальное делает. Забыл упомянуть об этом.

Ответы [ 3 ]

3 голосов
/ 17 февраля 2011

Решение и резюме:

Проблема возникает, когда пришло время кодировать кнопку отправки. Наши кнопки генерируются как <button ... ><span> Submit</span></button>; когда пришло время создавать запрос, все остальные браузеры, включая IE8, достаточно умны, чтобы принимать только «Отправить». IE7 отправляет весь внутренний HTML. У нас была эта ошибка в других контекстах, но на этот раз я получил неверный путь из-за ошибки JSON.

Я не могу и не буду переходить с <% Http.Button %> на вход; это вне меня, как это можно даже считать жизнеспособным решением; это расширение используется по очень веским причинам, и если бы я отказался от него, я бы не стал задавать этот вопрос.

Решение заключалось в добавлении нового фильтра, расширяющего RequestValidator, и проверке запроса на тег span, вызывающий сбой; если найдено, заменить текстом.

public class HttpRequestValidator : RequestValidator
{
    protected override bool IsValidRequestString(
            HttpContext context,
            string value,
            RequestValidationSource requestValidationSource,
            string collectionKey,
            out int validationFailureIndex)
    {
        // Check if the Request.QueryString contains a post value of "<span>.....</span>"
        if (requestValidationSource == RequestValidationSource.Form
              && !string.IsNullOrEmpty(value) && value.StartsWith("<span>",
            StringComparison.InvariantCultureIgnoreCase))
        {
            var match = Regex.Match(value, @"\A<span>(.*?)</span>\Z",
                RegexOptions.IgnoreCase);
            if (match.Success && match.Groups.Count > 1)
                return base.IsValidRequestString(
                    context, match.Groups[1].Value,
                    requestValidationSource,
                    collectionKey,
                    out validationFailureIndex);

        }

        return base.IsValidRequestString(
            context,
            value,
            requestValidationSource,
            collectionKey,
            out validationFailureIndex);
    }
}

Вам также необходимо добавить его в web.config; найдите httpRuntime и замените его на

<httpRuntime requestPathInvalidCharacters="&lt;,&gt;,*,%,:,\"
  requestValidationType=" ... .HttpRequestValidator"
  maxRequestLength="40920" maxQueryStringLength="10000"/>
1 голос
/ 15 февраля 2011

Вам необходимо скопировать / вставить свой код json в http://jsonlint.com/, чтобы проверить его правильность и увидеть проблему.

0 голосов
/ 15 февраля 2011

Возможно, вам лучше использовать обычный «входной» тег с типом кнопки, поскольку он находится внутри формы.По-видимому, IE 7 использует внутренний HTML-код кнопки в качестве значения, в то время как многие другие браузеры используют атрибут «value».

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