json - 如何解决 modelbinder 为 JSON post 转换(或不转换)空值的问题

标签 json jquery asp.net-mvc-4 model-binding

我一整天都在为一个 Action 而苦苦挣扎。由于某种原因,我似乎无法让模型绑定(bind)程序接受我的应用程序中的一些传入 JSON,尽管当我设置测试应用程序并传入相同的 JSON 时,模型绑定(bind)程序没有问题。

模型如下所示:

public class AdjustmentDefaultsModel
{
    public Guid EmployeeId { get; set; }
    public List<AdjustmentDefault> Adjustments { get; set; }
}

public class AdjustmentDefault
{
    public int Id { get; set; }
    public string EmployeeId { get; set; }
    public string AdjustmentTargetTypeId { get; set; }
    public string AdjustmentTargetId { get; set; }
    public string AdjustmentTargetTypeDescription { get; set; }
    public string AdjustmentTargetDescription { get; set; }
    public string Amount { get; set; }
}

为了完整起见,这是我的操作:

    [HttpPost]
    public JsonResult AddAdjustmentDefaults(AdjustmentDefaultsModel adjustments)
    {
        // will be more code here when I get the model in properly
        return Json(null);
    }

我的主项目和测试项目中由 Ajax 完成的帖子配置类似,唯一的区别是 url。测试器中的数据直接分配 JSON,而真实项目的数据是通过淘汰赛构建的:

            $.ajax({
                url: '/Employee/AddAdjustmentDefaults',
                crossDomain: true,
                data: ko.toJSON(self),
                contentType: "application/json; charset=utf-8",
                dataType: 'json',
                type: 'POST',
                success: function (data) { alert("Saved."); },
                error: function (error) { alert("Error."); },
            });

当我运行我的主项目时,我在 Fiddler 中捕获了失败的 JSON 并将其粘贴到测试项目中。如前所述,测试项目没有绑定(bind)问题。

以下 JSON 适用于我的主项目和测试项目:

{"EmployeeId":"cd930985-d66c-4d25-ae0c-253665242cf0","Adjustments":[]}

模型已正确填充 EmployeeId GUID,且调整属性为 null。

但是,当我尝试添加到列表中时,模型绑定(bind)程序崩溃了,不仅列表为空,而且员工 Guid 也为空。

我不知道从这里开始调试。很高兴知道模型绑定(bind)程序无法执行哪些操作,但我无法捕获这方面的任何有用信息。我是否必须构建自定义模型绑定(bind)器才能获取其不起作用的详细信息?

更新

根据 asymptoticFault 的评论,我继续为我的模型制作了一个自定义模型绑定(bind)器。代码如下所示:

public class AdjustmentDefaultsModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
            return null;    // not JSON request

        var request = controllerContext.HttpContext.Request;
        request.InputStream.Position = 0;
        var incomingData = new StreamReader(request.InputStream).ReadToEnd();

        if (String.IsNullOrEmpty(incomingData))
            return null;    // no JSON data

        return JsonConvert.DeserializeObject(incomingData, bindingContext.ModelType);
    }
}

使用此模型绑定(bind)器,我的操作现在可以生成具有所有正确值的模型。

不知道为什么会这样。虽然我还没有下载 DefaultModelBinder 源来验证,但在我看来,这基本上就是它应该做的事情。毕竟,DefaultModelBinder 似乎适用于绝大多数传入的 JSON...那么为什么不使用这个呢?

所以我的实际问题仍然没有得到真正的解答,但我不能在这个问题上浪费太多时间,因为它比我最初估计的预算 10 分钟多花费了大约 6 个小时的时间。 (叹气。)

最佳答案

尝试使用自定义模型绑定(bind)器,它最终可能不是必需的,但它将帮助您调试传递到服务器的值实际发生的情况。

这是一个非常简单的过程,实际上只需两个步骤:

1) 创建一个实现 System.Web.Mvc.IModelBinder 接口(interface)的类,我相信它只是一个方法,BindModel()

2) 在 Global.asax.csOnApplicationStart() 方法中添加绑定(bind)器,如下所示

ModelBinders.Binders.Add(typeof(AdjustmentDefaultsModel), new YourModelBinder());

关于json - 如何解决 modelbinder 为 JSON post 转换(或不转换)空值的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18217658/

相关文章:

json - Ktor:如何验证 JSON 请求?

java - 如何在Java中解析具有分隔的json对象的文本文件?

jquery - JSONP:是否需要回调?

javascript - 选择菜单选项未按预期显示或隐藏

asp.net-mvc-4 - 如何从远程计算机调试 Visual Studio 2012 中的 Asp.Net Mvc 应用程序

json - 如何配置 F# JSON 类型提供程序以对 POST 请求使用 UTF-8?

jquery - 放大和淡出效果

razor - 输入隐藏显示不正确的 ID (Guid.Empty)

c# - MVC4 的严重 OAuth 问题

json - 如何在 bash 脚本中遍历 json