9

在 ASP.Net MVC 中向我的控制器发布帖子时,我希望能够发送 JSON 而不是标准 QueryStrings。我的前端工作正常(构建然后提交我的 JSON 对象)。

问题出在控制器端,MVC 框架附带的默认 ModelBinders 不支持这一点。

我已经看到了解决此问题的多种方法,其中之一是应用一个将对象作为参数的过滤器,使用 JSON 库对其进行反序列化,并将其添加到操作参数中。这并不理想。

另一种更好的方法是使用自定义模型绑定器。尽管我所看到的所有模型都假设您只有一个模型,并且这将是一个类而不是一个变量。如果你有多个,它会崩溃。

有人遇到过这种情况么?我的一个想法是,如果我可以简单地覆盖 MVC 如何处理 FormCollection 并在那里拦截,我自己将值添加到集合中,并希望 MVC 能够以正常的方式完成其余的工作。有谁知道这是否可能?

我认为,关键问题在于我的问题不在于绑定,因为我的视图模型与以前的视图模型没有什么不同。问题是从 JSON Post 获取值。

如果我是正确的,MVC 从 QueryString 中获取值并将其放入表单集合中,然后用于 ModelBinding。那么正确的方法不应该是改变 FormCollection 的分配方式吗?

动作示例:

public ActionResult MyFirstAction(Int32 ID, PersonObject Person, ClassObject ClassDetails)
{
//etc
}

普通绑定有效,JSON 无效,模型绑定器的所有示例也无效。到目前为止,我最好的解决方案是将对象转换为字典并循环遍历每个参数并将其匹配。似乎不太理想。

4

1 回答 1

8

我为 json 使用自定义模型绑定器,如下所示:

public class JsonModelBinder<T> : IModelBinder {
    private string key;

    public JsonModelBinder(string requestKey) {
        this.key = requestKey;
    }

    public object BindModel(ControllerContext controllerContext, ...) {
        var json = controllerContext.HttpContext.Request[key];
        return new JsonSerializer().Deserialize<T>(json);
    }
}

然后将其连接到 Global.asax.cs 中,如下所示:

ModelBinders.Binders.Add(
    typeof(Product),
    new JsonModelBinder<Product>("ProductJson"));

您可以在此处阅读有关此内容的更多信息:继承是邪恶的:DataAnnotationsModelBinder 的史诗般的失败

编辑

JsonModelBinder 应仅用于类型为 Product 的控制器操作参数。Int32 和 ClassObject 应该回退到 DefaultModelBinder。您是否遇到不同的结果?

于 2010-01-26T16:42:42.117 回答