从 ASP.NET MVC 返回 null 时,jQuery post JSON 失败
Posted
技术标签:
【中文标题】从 ASP.NET MVC 返回 null 时,jQuery post JSON 失败【英文标题】:jQuery post JSON fails when returning null from ASP.NET MVC 【发布时间】:2013-04-03 03:02:02 【问题描述】:我使用ASP.NET MVC 从 jQuery 发布 JSON,并使用这个小库函数返回一些 JSON:
(function($)
$.postJson = function(url, data)
return $.ajax(
url: url,
data: JSON.stringify(data),
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8'
);
;
)(jQuery);
所以很明显我会这样称呼它:
$('#button').click(function()
$.postJson('/controller/action', Prop1: 'hi', Prop2: 'bye' )
.done(function(r) alert('It worked.'); )
.fail(function(x) alert('Fail! ' + x.status); );
);
ASP.NET MVC 3 和 ASP.NET MVC 4 支持事物的提交方面(在此之前您需要扩展 ASP.NET MVC 以处理提交 JSON),但我遇到的问题是返回。在控制器上,我经常返回 null 基本上是说“成功,没什么好说的”,例如:
[HttpPost]
public JsonResult DoSomething(string Prop1, string Prop2)
if (doSomething(Prop1, Prop2)
return Json(null); // Success
return Json(new Message = "It didn't work for the following reasons" );
我经常使用这种模式,它工作正常 - 我的成功/完成回调被调用,一切都很好。但最近我升级了 ASP.NET MVC 和 jQuery,但它停止了工作 - 相反,每当我 return Json(null);
时,我的失败回调就会被调用。此外,我检查了响应,返回的 statusCode 实际上是 200,所以服务器没有失败 - jQuery 只是说它是。
【问题讨论】:
顺便说一句,exception.message
中的全局 $(document).ajaxError...
显示:“Unexpected end of input”当 Json(null)
返回时(只是提一下,它没有帮助我来找出问题的原因)。
【参考方案1】:
问题是从 jQuery 1.8 升级到 1.9 引起的。在 jQuery 1.7 和 1.8 中,这在 MVC 中:
return Json(null);
被接受为有效的 JSON 并被解释为 null。从技术上讲,这会使用 HTTP 200 向客户端发送一个空白字符串,这对于 jQuery
但是现在(我们使用 jQuery 1.9.1),它尝试将空字符串解析为 JSON,jQuery 的 JSON 解析器在空字符串上抛出异常,并触发以 fail()
回调结尾的代码链而是。
一种解决方法是在成功时将其从服务器传回,而不提供其他信息:
return Json(new);
通过 jQuery 的 JSON 解析器,一切顺利。这也有效:
return Json(true);
更新
Musa 在 MVC 的这种行为下面的注释似乎被破坏了。这个separate Stack Overflow answer to Using JSON.NET as the default JSON serializer in ASP.NET MVC 3 - is it possible? 介绍了如何让 MVC 为 Json(null)
返回 null - 基本上,使用 Json.NET 而不是 ASP.NET MVC 的内置 JSON 序列化程序。这是我最终使用的解决方案。
但是,您需要使用该答案的略微修改版本来解决此问题 - 代码如下。基本上,在传递给序列化之前不要包含检查 null 的 if
语句,否则你又会陷入同样的困境。
更新 2
Json.NET 中 ISO 8601 日期的默认实现在尝试使用 new Date(...)
解析它时会破坏 Internet Explorer 9 及以下。换句话说,这些在 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);
演示如何将其绑定到 BaseController 的要点:
https://gist.github.com/b9chris/6991b341e89bb0a4e6d801d02dfd7730
【讨论】:
return Json(null);
返回一个空字符串听起来很糟糕,它应该返回null
@Musa 可能,尽管在这一点上这也可能是一个突破性的变化——我去挖掘了,它似乎从 MVC 的开始就返回了一个空字符串。我确实同意这可能是解决这个问题的更清洁的方法。这个答案涵盖了这样做,尽管示例代码在 Json.Net 可以尝试之前检查 null 并返回空字符串 - 删除这 2 行,您将得到未修改的 null 返回。 ***.com/a/7150912/176877以上是关于从 ASP.NET MVC 返回 null 时,jQuery post JSON 失败的主要内容,如果未能解决你的问题,请参考以下文章
如何从 ASP.NET MVC 控制器返回 Ajax“失败”?
ASP.NET MVC 接收“null”作为字符串而不是 null
ASP.NET Web API将MV响应转换为MVC 4中的json List