简体   繁体   English

ASP.NET MVC:如何创建将绑定到此POST数据的模型?

[英]ASP.NET MVC: How to create a model that will bind to this POSTed data?

I'm having trouble creating a model that will bind to the form data below . 我在创建将绑定到下面的表单数据的模型时遇到了麻烦。 The main difficulty I'm having is creating a model that will bind the filter (ie: the multi-dimensional array). 我遇到的主要困难是创建一个将绑定filter的模型(即:多维数组)。

This is what I have so far. 到目前为止,这就是我所拥有的。 Can anyone help me to get this model to bind properly? 谁能帮助我使此模型正确绑定?

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

    }

发布数据

Update 更新

After reading the capabilities of DefaultModelBinder, I saw the problem in the post data. 阅读了DefaultModelBinder的功能后,我在发布数据中看到了问题。

Before anything, just change the class of the filter property to: 在进行任何操作之前,只需将filter属性的类更改为:

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

Here is a query string that the DefaultModelBinder will Bind correctly: 这是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

But js is generating this query string: 但是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

Now you can implement your own ModelBinder class, but I think is easier to serialize the object on the client side, just make sure that the content type is properly set. 现在您可以实现自己的ModelBinder类,但是我认为在客户端上序列化对象会更容易,只需确保正确设置内容类型即可。 Here is an example made in jquery: 这是在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>

Then you only add this line to your Application_Start method in global.asax file: 然后,仅将此行添加到global.asax文件中的Application_Start方法中:

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

That way the framework will bind correctly the model, and in the action method you'll receive the object 这样,框架将正确地绑定模型,并且在action方法中,您将收到对象

    [HttpPost]
    public ActionResult ReceivePostFromJson(GetPagedRequest g)
    {

Original Answer 原始答案

If you could Stringify the json from the control, before posting the filter data, then you could use JavaScriptSerializer to Deserialize the object. 如果可以在发布过滤器数据之前从控件中对JSON进行字符串化处理,则可以使用JavaScriptSerializer对对象进行反序列化。

This example is made in jquery: 这个例子是用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>

Then in the controller: 然后在控制器中:

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

    return View(obj);
}

That way you have the nested objects: 这样,您就有了嵌套的对象: Json MVC测试屏幕截图

Note: In this example if you remove the function JSON.stringify (data: filterData,), you'll see on the controller side the query string that produce your problem (filter[0][field]: CompanyName). 注意:在此示例中,如果删除函数JSON.stringify (数据:filterData,),则将在控制器端看到产生问题的查询字符串(filter [0] [field]:CompanyName)。 I don't know if there's a way to recover the json, if it's possible then you don't have to modify the grid control: 我不知道是否有恢复json的方法,如果可能的话,则不必修改网格控件: JS对象制作表格

I do not support the solution from jherrera: 我不支持jherrera的解决方案:

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

    return View(obj);
}

if you want to recieve json data from the client on server side you should prepare your client side object to have the save structure like the server side viewmodel. 如果要从服务器端的客户端接收json数据,则应准备客户端对象以具有类似于服务器端viewmodel的保存结构。 That way the model binder will do its job perfectly when the form is submitted. 这样,当提交表单时,模型联编程序将完美地完成其工作。

code not tested: 代码未经测试:

public ActionResult DeleteXXX(GetPagedRequest pagedRequestViewModel)
{
   // Use AutoMapper or a UI Service to reshape/map your viewmodel to your domain model
   return EmptyResult();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM