How to Accept an Array as an ASP.NET MVC Controller Action Parameter

How do I accept an array as an ASP.NET MVC controller action parameter?

The default model binder expects this url:

http://localhost:54119/Designs/Multiple?ids=24041&ids=24117

in order to successfully bind to:

public ActionResult Multiple(int[] ids)
{
...
}

And if you want this to work with comma separated values you could write a custom model binder:

public class IntArrayModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
if (value == null || string.IsNullOrEmpty(value.AttemptedValue))
{
return null;
}

return value
.AttemptedValue
.Split(',')
.Select(int.Parse)
.ToArray();
}
}

and then you could apply this model binder to a particular action argument:

public ActionResult Multiple([ModelBinder(typeof(IntArrayModelBinder))] int[] ids)
{
...
}

or apply it globally to all integer array parameters in your Application_Start in Global.asax:

ModelBinders.Binders.Add(typeof(int[]), new IntArrayModelBinder());

and now your controller action might look like this:

public ActionResult Multiple(int[] ids)
{
...
}

How to send an array using Url.Action

It will not bind like that.
To get the id array in your action you need to have the link at the end like this: *Dispatch/ExportData?id=1&id=2&id=3*

Your "@Url.Action("ExportData", "Dispatch")?id=" + data; will not generate that (data will give the numbers separated with commas).

You can just build the query string when you enumerate the checkboxes.

function SeeStation() {
var data = '';
$("input:checkbox:checked").each(function () {
data += 'id='$(this).val() + '&';
});
window.location.href = "@Url.Action("ExportData", "Dispatch")?" + data;
}

You will have a "&" in the end. You can easily remove it, but it will not affect anything.

There may be better ways to do this though, but I just used your function.

ASP.NET MVC parameter binding: How to POST a list or array to a controller method?

Here is what's really happening:

itemIds is being posted as one single string to the controller. Why? Because itemIds is not interpreted as an array. If you want an array, you need to have multiple hidden values named itemIds[0], itemsIds[1] and so on. Here is a quick test to prove that what I am saying is actually what is happening:

Create a form like this. See we create one hidden value named itemIdsOld and then 2 more hidden values named itemIds[0] and itemIds[1]:

<form method="post" action="/Foo/Bar">
<input name="itemIdsOld" type="hidden" value="["f8b21933-419c-4bdd-b5b6-75295ff65612","67bb1d75-ae78-49e4-bc29-ee82a51bb9a1"]">
<input name="itemIds[0]" type="hidden" value="f8b21933-419c-4bdd-b5b6-75295ff65612">
<input name="itemIds[1]" type="hidden" value="67bb1d75-ae78-49e4-bc29-ee82a51bb9a1">
<button type="submit">Submit</button>
</form>

Create a controller like this:

[System.Web.Mvc.HttpPost]
public ActionResult Index(string[] itemIdsOld, Guid[] itemIds)
{
return null;
}

When you post the above form, you will notice that a single string is created in itemIdsOld and it will have both the Guids in it as a string. However, the second one, since we created controls named itemIds[0] and itemIds[1] will be converted to a Guid[] itemIds as you expected.

I am not sure how to do this in Angular, but with C# and Razor, one way to do it would be like this:

@using System.Collections.Generic
@{
var guids = new List<Guid> { Guid.NewGuid(), Guid.NewGuid() };
}
<form method="post" action="/Test/Index">
<input name="itemIdsOld" type="hidden" value="["f8b21933-419c-4bdd-b5b6-75295ff65612","67bb1d75-ae78-49e4-bc29-ee82a51bb9a1"]">
@{
for (int i = 0; i < guids.Count; i++)
{
<input name="itemIds[@i]" type="hidden" value="@guids[i]">
}
}
<button type="submit">Submit</button>
</form>

I hard coded the guids but you can get this from a model...you get the point.


Alternatively, you can use Javascript to intercept the form submission and retrieve the value from itemIds and turn it into an array and submit that to the controller, that would work too.

Sending an array through action link or url action and accept in route table in MVC4

you can do it with Json let suppose i have array

ViewBag.array = new[] {"test1", "test2", "test3"};

so my view would be something like

@Html.ActionLink("link","test",new {array= Json.Encode(ViewBag.array) })

Json.Encode will convert this array to json string

and my test action will be like this

 public ActionResult test (string array)
{
string[] result = System.Web.Helpers.Json.Decode<string[]>(array);

return View();

}

Json.Decode<string[]> will convert this json string back to string[] array

pass array of array to the controller not working in asp.net mvc

You should accept array of objects instead of string, as you are passing object array from ajax.

So create a model for same.

public class Mail
{
public string value {get;set;}
public string item {get;set;}
}

public class Test
{
public string categoryId {get;set;}
public Mail[] selectedMail {get;set;}
public Mail[] selectedMobile {get; set;}
}

Then

    [HttpPost]
public ActionResult UtilityEmailSMS(Test[] data)
{

return View();
}

Passing int array to MVC controller

best practise for a post action will be to use the body to send parameters for post (Note the [FromBody] annotation of paramters):

[HttpPost]
public async Task<ActionResult> Filter([FromBody] int[] locations, [FromBody] int[] machines, [FromBody] int[] severities, [FromBody] int[] messages)

the parameters needs to be specified in the body of the ajax call:

function Filter(locations, machines, severities, messages) {
var url = '@Url.Action("Filter", "ActiveMessages")';
$.ajax({
url: url,
method: 'POST',
data: JSON.stringify({ locations: locations, machines: machines, severities: severities, messages: messages }),
traditional: true,
success: function (data) {
}});
}

Passing an int array to MVC Controller

To pass an array of simple values in MVC, you simply need to give the same name to multiple values e.g. The URI will end up looking something like this

/{controllerName}/EditAll?ids=1&ids=2&ids=3&ids=4&ids=5¤tId=1

The default model binding in MVC will bind this to the int array Action parameter correctly.

Now, if it were an array of complex values, there are two approaches that can be taken for model binding. Let's suppose you have a type like so

public class ComplexModel
{
public string Key { get; set; }

public string Value { get; set; }
}

and a controller action signature of

public virtual ActionResult EditAll(IEnumerable<ComplexModel> models)
{
}

For model binding correctly, values need to include an indexer in the request e.g.

/{controllerName}/EditAll?models[0].Key=key1&models[0].Value=value1&models[1].Key=key2&models[1].Value=value2

We're using an int indexer here but you can imagine that this might be quite inflexible in an application where items presented to a user in the UI can be added and deleted at any index/slot in the collection. For this purpose, MVC also allows you to specify your own indexer for each item in the collection and pass that value in with the request for the default model binding to use e.g.

/{controllerName}/EditAll?models.Index=myOwnIndex&models[myOwnIndex].Key=key1&models[myOwnIndex].Value=value1&models.Index=anotherIndex&models[anotherIndex].Key=key2&models[anotherIndex].Value=value2

Here we have specified our own indexers, myOwnIndex and anotherIndex for model binding to use to bind a collection of complex types. You can use any string for your indexers as far as I am aware.

Alternatively, you can implement your own model binder to dictate how an incoming request should be bound to a model. This requires more work than using the default framework conventions but does add another layer of flexibility.

Pass array of objects to MVC Controller Action via JQuery AJAX, Action Parameter is always null

Your action parameter is null because you have to fix the way you are sending the data property from your ajax to this:

$.ajax({
type: "POST",
url: serviceURL,
data: JSON.stringify({ 'lstmixing': DATA }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {...

And finally you have another possible problem when inserting the data in the array. I mean this line:

DATA.push("{'MIXINGNO':'" + MIXINGNO + "','DATE': '" + DATE + "','INVOICEDETAILID': '" + INVOICEDETAILID + "','CARET': '" + CARET + "','PRICE': '" + PRICE + "','DETAILS': '" + DETAILS + "'}");

You are trying to insert into the array objects like they already are objects type JSON, the way you have to do this is inserting them like javascript normal objects, like this:

DATA.push({
MIXINGNO: MIXINGNO,
DATE: DATE,
INVOICEDETAILID: INVOICEDETAILID,
CARET: CARET,
PRICE: PRICE,
DETAILS: DETAILS
});


Related Topics



Leave a reply



Submit