Pass array of inputs to a MVC controller

1

I have the following Ajax and HTML code.

 $("#filter_frm").submit(function (e) {
    e.preventDefault();


        var data = $(this).serialize();
        myChart.showLoading({
            text: 'Cargando',
            color: '#c23531',
            textColor: '#000',
            maskColor: 'rgba(255, 255, 255, 0.8)',
            zlevel: 0
        });
        $(".chart_container").show();
        $.ajax(
            {
                url: "/calls/received",
                type: "post",
                contentType: 'application/json',
                data: data,
                traditional: true,
                success: function (response) {
...

<form action="/calls/received" method="post" id="filter_frm" autocomplete="off" enctype="multipart/form-data">
     <div class="form-group">
            <select id="filter" class="form-control js-data-example-ajax col-sm-12" multiple="">
                       <option value="x" name="valor[]">
                       <option value="x" name="valor[]">
                                        </select>
                                    ...

I serialize the array of OPTIONS but when I move to the MVC controller it comes to me as an error.

    [HttpPost]
    [Route("calls/received")]
    public ContentResult Received(List<String> users)
    {
          ...
    }

Why can it be? Thanks.

    
asked by Aritz Ezkiaga 16.11.2018 в 11:35
source

1 answer

1

There are several things to highlight here. Let's see if I can help you.

Incorrect ContentType.

If you are sending the serialized form, the contentType should not be application/json . Remove it from the request .

How does $(form).serialize() work?

If to this function of jquery we pass a html form (as in your case), the "successful" elements (sounds weird but they are called like that, see this link for more info) of the form are serialized to a string in URL encoded notation (URL-encoded notation). One of the things that must have a control to be serialized, is that it has a name (attribute name) so in your example the select must have a name .

<form action="/calls/received" method="post" id="filter_frm" ... >
     <div class="form-group">
        <select name="filter" ... >
            ...
        </select>
</form>

MVC Model Binder.

When you send the form to the controller, the model binder (who is responsible for interpreting the content of the request and filling the parameters of the action in an intelligent way) must be able to find in the content of the request the keys that they correspond to the object you want to receive.

So in your case, as your action receives a list of chains called users you need to make sure to send that same name in your request. This can be changed and modified, manipulating the parameters of the model binder, but it is best not to fight against the framework.

I will assume that you want to receive the filters in the controller instead of something called users that you might have in another form control, so I will change the name of the parameter to filter in the action:

[HttpPost]
[Route("calls/received")]
public JsonResult Received(string[] filter)
{   
    return Json(filter);
}

By way of illustration I will only send the value of the filters to the view as I received them. But obviously this is where you would have to manipulate those filters and invoke a service class or repository to execute some business operation.

Notice that I deliberately changed the type of the parameter to be an array of string ( string[] ) instead of a list ( List<string> ) to show that the model binder is smart enough to know how to fill that object does not matter if it is list or arrangement.

Summing up

With all these changes I think you can go ahead with this. I leave this fiddle here so you can see this example working.

Example: link

I hope it serves you!

    
answered by 16.11.2018 в 16:08