Ответ 1
Проблема была вызвана обновлением с jQuery 1.8 до 1.9. В jQuery 1.7 и 1.8 это в MVC:
return Json(null);
был принят как действительный JSON и интерпретирован как null. Технически это отправляет пустую строку обратно клиенту с HTTP 200, и это достаточно хорошо для jQuery < 1.9.
Но теперь (мы используем jQuery 1.9.1), он пытается разобрать пустую строку как JSON, JSON-парсер jQuery генерирует исключение в пустой строке и запускает цепочку кодов, которая заканчивается обратным вызовом fail()
вместо этого.
Обходной путь заключается в том, чтобы вместо этого вернуть сервер с успехом без дополнительной информации:
return Json(new{});
Это передается с парсером JQuery JSON, и все хорошо. Это также работает:
return Json(true);
Update
Заметки Мусы ниже этого поведения MVC кажутся нарушенными. Этот отдельный ответ на использование JSON.NET в качестве сериализатора JSON по умолчанию в ASP.NET MVC 3 - возможно ли это? описывает, как получить MVC для возврата null для Json(null)
- в основном, используйте Json.NET вместо ASP.NET MVC встроенного JSON-сериализатора. Это решение, которое я в конечном итоге использовал.
Вам нужно использовать слегка измененную версию этого ответа, чтобы исправить это, но код ниже. В принципе, не включайте оператор if
, проверяющий значение null, прежде чем перейти к сериализации, или вы вернетесь в то же самое затруднение.
Обновление 2
Стандартная реализация ISO 8601 Dates в Json.NET прерывает Internet Explorer 9 и ниже, когда он пытается проанализировать ее с помощью new Date(...)
. Другими словами, эти синтаксические разборки в Internet Explorer 9:
var date = new Date('2014-09-18T17:21:57.669');
var date = new Date('2014-09-18T17:21:57.600');
Но это вызывает исключение:
var date = new Date('2014-09-18T17:21:57.6');
Internet Explorer 9. Функция Date() не может справиться ни с чем, а ровно три миллисекунды. Чтобы исправить это, вы должны переопределить формат даты Json.NET, чтобы заставить его. Включено в код ниже.
public class JsonNetResult : JsonResult
{
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");
var response = context.HttpContext.Response;
response.ContentType = !String.IsNullOrEmpty(ContentType) ? ContentType : "application/json";
if (ContentEncoding != null)
response.ContentEncoding = ContentEncoding;
var settings = new JsonSerializerSettings
{
Converters = new[] {new IsoDateTimeConverter
{
DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffK"
}}
};
var jsonSerializer = JsonSerializer.Create(settings);
jsonSerializer.Serialize(response.Output, Data);
}
}
A Gist, демонстрирующий, как связать это с BaseController:
https://gist.github.com/b9chris/6991b341e89bb0a4e6d801d02dfd7730