简体   繁体   中英

Pass Comma Separated Value to ASP.NET MVC Action Method

Ok so I basically have an ajax call retrieving values from html select multiple tag ... Thing is I'm not able to pass these values into my controller (I'm getting a null reference in my controller)

Check types: $('select#opt2').val() in the ajax call. avion: $('select#opt1').val() isn't a multiple values so it works fine. When I alert($('select#opt2').val()) I get values like: GC,VSG,AA7... (They are separated by ",")

Here's my code:

AJAX

$('select#opt2').change(function () {
            $.ajax({
                url: '@Url.Action("RetournerPostes", "Home", new { area = "Avion" })',
                data: { avion: $('select#opt1').val(), types: $('select#opt2').val() },
                type: 'POST',
                dataType: 'JSON',
            //Rest of code

CONTROLLER This is where I get the null reference for variable "types"

[HttpPost]
    public async Task<ActionResult> RetournerPostes(string avion,List<string> types)
    {
       //Rest of action

Tell me if you need any more information. Thanks!

EDIT

Added fiddle: https://jsfiddle.net/f73jxo5v/

If you bind comma separated value (CSV) a lot, the easiest and maintainable way is to create a custom model binder called CommaSeparatedModelBinder.

It is not common to capture select 's change event, and make an Ajax call whenever user selects an option. But it is up to you.

在此处输入图片说明

在此处输入图片说明

[HttpGet]
public ActionResult RetournerPostes()
{
    return View();
}

[HttpPost]
public ActionResult RetournerPostes(string avion, 
    [ModelBinder(typeof(CommaSeparatedModelBinder))] int[] types)
{
    return View();
}

View

@using (Html.BeginForm())
{
    <select id="opt1">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
    </select>

    <select id="opt2" multiple>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
    </select>
    <input type="submit" value="Submit"/>
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
    $('select#opt2').change(function () {
        var data = JSON.stringify({ avion: $('select#opt1').val(), types: $('select#opt2').val() });
        console.log(data);
        $.ajax({
            url: '@Url.Action("RetournerPostes", "Home")',
            data: data,
            type: 'POST',
            contentType: "application/json",
            dataType: 'JSON',
            success: function(msg) {
                console.log(msg);
            }
        });
    });
</script>

CommaSeparatedModelBinder

public class CommaSeparatedModelBinder : DefaultModelBinder
{
    private static readonly MethodInfo ToArrayMethod = typeof(Enumerable).GetMethod("ToArray");

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        return BindCsv(bindingContext.ModelType, bindingContext.ModelName, bindingContext)
                ?? base.BindModel(controllerContext, bindingContext);
    }

    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
    {
        return BindCsv(propertyDescriptor.PropertyType, propertyDescriptor.Name, bindingContext)
                ?? base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
    }

    private object BindCsv(Type type, string name, ModelBindingContext bindingContext)
    {
        if (type.GetInterface(typeof(IEnumerable).Name) != null)
        {
            var actualValue = bindingContext.ValueProvider.GetValue(name);

            if (actualValue != null)
            {
                var valueType = type.GetElementType() ?? type.GetGenericArguments().FirstOrDefault();

                if (valueType != null && valueType.GetInterface(typeof(IConvertible).Name) != null)
                {
                    var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(valueType));

                    foreach (var splitValue in actualValue.AttemptedValue.Split(new[] { ',' }))
                    {
                        if (!String.IsNullOrWhiteSpace(splitValue))
                            list.Add(Convert.ChangeType(splitValue, valueType));
                    }

                    if (type.IsArray)
                        return ToArrayMethod.MakeGenericMethod(valueType).Invoke(this, new[] { list });

                    return list;
                }
            }
        }

        return null;
    }
}

Original Source: CommaSeparatedModelBinder.cs

That's because what you are passing as types, are a string object and not as string list.

You will have to cast the types variable into an array of string:

var array = string.split(','); 

and pass it as an array to the method, not as a list:

[HttpPost]
    public async Task<ActionResult> RetournerPostes(string avion, string[] types)
    {

Hope this will sort out your problem:

       $('select#opt2').change(function () {
        var stringArray = new Array();
        stringArray =$("#opt2>option").map(function() { return $(this).text(); }).get();
        var selectedValue = $('select#opt2').val();
        $.ajax({
            url: '@Url.Action("RetournerPostes", "Home", new { area = "Avion" })',
            data: {avion: selectedValue, types: stringArray},
            type: 'POST',
            dataType: 'JSON',
        //Rest Code

if your types = "GC,VSG,AA7" then you are passing a string, not a list of strings, so:

public async Task<ActionResult> RetournerPostes(string avion, string types){
    var myArray = types.Split(','); // split into an array
}
types= []
var sel = $('#selectID');
for (var i=0, n=sel.options.length;i<n;i++) { // looping over the options
  if (sel.options[i].value) types.push(sel.options[i].value);
}

then pass types to your controller without changing ur server code

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