3

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

该模型如下所示:

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 并将其粘贴到测试项目中。如前所述,测试项目的绑定没有问题。

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

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

该模型具有正确填充的 EmployeeId GUID,并且 Adjustments 属性为空。

但是,当我尝试将模型绑定器添加到列表中时,不仅列表为 null,而且员工 Guid 也为 null。

我不知道从哪里调试。很高兴知道模型绑定器没有做什么,但我无法捕捉到任何在这方面有用的东西。我是否必须构建自定义模型绑定器才能了解为什么这不起作用?

更新

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

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

使用此模型绑定器,我的 Action 现在会生成具有所有正确值的模型。

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

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

4

1 回答 1

1

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

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

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

2)用类似的OnApplicationStart()方法添加binderGlobal.asax.cs

ModelBinders.Binders.Add(typeof(AdjustmentDefaultsModel), new YourModelBinder());
于 2013-08-14T02:44:08.883 回答