2

我在创建将绑定到以下表单数据的模型时遇到问题。我遇到的主要困难是创建一个将绑定filter(即:多维数组)的模型。

这就是我到目前为止所拥有的。谁能帮我让这个模型正确绑定?

 public class GetPagedRequest
    {
        public int Start { set; get; }

        public int Limit { set; get; }

        public string dir { set; get; }

        public List<FilterRequest> filter { set; get; } //This won't bind properly

    }

    public class FilterRequest
    {
        public string field { set; get; }

        public DataFilterRequest data { set; get; }
    }

    public class DataFilterRequest
    {
        public string type { set; get; }
        public string value { set; get; }

    }

发布数据

4

2 回答 2

0

更新

看了DefaultModelBinder的能力后,在post数据中看到了问题。

在任何事情之前,只需将过滤器属性的类更改为:

public IList<FilterRequest> filter { set; get; } //(IList<T> instead of List<T>)

这是 DefaultModelBinder 将正确绑定的查询字符串:

start=0&limit=5&dir=ASC&sort=noSort&filter[0].field=CompanyName&filter[0].data.type=string&filter[0].data.value=Telus&filter[1].field=VendorName&filter[1].data.type=string&filter[1].data.value=testtest

但是 js 正在生成这个查询字符串:

start=0&limit=5&dir=ASC&sort=noSort&filter[0][field]=CompanyName&filter[0][data][type]=string&filter[0][data][value]=Telus&filter[1][field]=VendorName&filter[1][data][type]=string&filter[1][data][value]=testtest

现在您可以实现自己的 ModelBinder 类,但我认为在客户端序列化对象更容易,只需确保正确设置内容类型即可。这是一个用jquery制作的例子:

<script type="text/javascript">
    $(function () {
        $("#btnSendPost").click(function () {
            var filterData = {
                "start": 0, "limit": 5,
                "dir": "ASC", "sort": "noSort",
                "filter": [{ "field": "CompanyName", "data": { "type": "string", "value": "Telus" } },
                           { "field": "VendorName", "data": { "type": "string", "value": "testtest" } }]};
            $.ajax({
                type: "POST",
                url: "/Home/ReceivePostFromJson",
                data: JSON.stringify(filterData),
                dataType: "json",
                contentType: 'application/json; charset=utf-8'
            });
        });
    });
</script>

然后,您只需将此行添加到 global.asax 文件中的 Application_Start 方法:

ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

这样框架将正确绑定模型,并且在 action 方法中您将收到对象

    [HttpPost]
    public ActionResult ReceivePostFromJson(GetPagedRequest g)
    {

原始答案

如果您可以在发布过滤器数据之前将控件中的 json 字符串化,那么您可以使用 JavaScriptSerializer 来反序列化对象。

这个例子是用jquery制作的:

<script type="text/javascript">
    $(function () {
        $("#btnSendPost").click(function () {
            var filterData = {
                "start": 0, "limit": 5,
                "dir": "ASC", "sort": "VendorName",
                "filter": [{ "field": "CompanyName", "data": { "type": "string", "value": "Telus" } },
                           { "field": "VendorName", "data": { "type": "string", "value": "testtest" } }]};
            $.ajax({
                type: "POST",
                url: "/Home/ReceivePostFromJson",
                data: JSON.stringify(filterData),
                dataType: "application/json"
            });
        });
    });
</script>

然后在控制器中:

[HttpPost]
public ActionResult ReceivePostFromJson()
{
    string jsonStringify = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
    var obj = new JavaScriptSerializer().Deserialize<GetPagedRequest>(jsonStringify);

    return View(obj);
}

这样你就有了嵌套的对象: Json MVC 测试截图

注意:在此示例中,如果您删除函数 JSON.stringify (data: filterData,),您将在控制器端看到产生问题的查询字符串 (filter[0][field]: CompanyName)。我不知道是否有办法恢复 json,如果可能的话,你不必修改网格控件: JS对象制作形式

于 2013-03-15T06:41:43.340 回答
0

我不支持 jherrera 的解决方案:

[HttpPost]
public ActionResult ReceivePostFromJson()
{
    string jsonStringify = new System.IO.StreamReader(Request.InputStream).ReadToEnd();
    var obj = new JavaScriptSerializer().Deserialize<GetPagedRequest>(jsonStringify);

    return View(obj);
}

如果您想从服务器端的客户端接收 json 数据,您应该准备您的客户端对象以具有类似于服务器端视图模型的保存结构。这样,模型绑定器将在提交表单时完美地完成其工作。

代码未测试:

public ActionResult DeleteXXX(GetPagedRequest pagedRequestViewModel)
{
   // Use AutoMapper or a UI Service to reshape/map your viewmodel to your domain model
   return EmptyResult();
}
于 2013-03-16T09:39:35.157 回答