简体   繁体   中英

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).

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.

Before anything, just change the class of the filter property to:

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

Here is a query string that the DefaultModelBinder will Bind correctly:

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:

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. Here is an example made in 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:

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

That way the framework will bind correctly the model, and in the action method you'll receive the object

    [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.

This example is made in 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). 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: JS对象制作表格

I do not support the solution from 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. 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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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