首页>Program>source

我使用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只是这么说。

最新回答
  • 11天前
    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,jQuery的JSON解析器对空字符串抛出异常,并触发以 fail()结尾的代码链 回调。

    一种解决方法是,在没有其他信息的情况下成功地将其从服务器传回:

    return Json(new{});
    

    这通过jQuery的JSON解析器传递请求,一切都很好.这也可以:

    return Json(true);
    


    更新

    Musa指出,MVC的以下行为似乎已损坏.使用JSON.NET作为ASP.NET MVC 3中的默认JSON序列化程序的单独堆栈溢出答案-有可能吗?涵盖了如何使MVC为 Json(null)返回null -基本上,请使用Json.NET而不是ASP.NET MVC的内置JSON序列化程序.这是我最终使用的解决方案。

    您需要使用对该答案的稍作修改的版本才能解决此问题-代码如下.基本上,不包括 if 语句在传递给序列化之前检查是否为null,否则您将陷入同样的​​困境。


    更新2

    Json.NET中ISO 8601日期的默认实现在尝试使用 new Date(...)解析InternetExplorer9及以下版本时会中断InternetExplorer9及以下版本 .换句话说,这些解析在InternetExplorer9中很好:

    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');
    

    InternetExplorer9的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

  • 高性能"包含" C#字符串列表中的搜索
  • events:Javascript:如何启用stopPropagation?