# Passing an array of values in Url.Action

I need to pass an array of values in Url.Action.

Currently I'm doing:

var redirectUrl = Url.Action("search", new {
q = criteria.Q,
salaryfrom = criteria.SalaryFrom,
salaryto = criteria.SalaryTo,
});

if (criteria.JobTypes != null)
redirectUrl += criteria.JobTypes.Aggregate(string.Empty, (a, x) => a += "&jobTypes=" + x);


To give me something like:

/search?q=developer&advanced=false&salaryfrom=20000&salaryto=80000&jobTypes=Full%20Time&jobTypes=Contract


Is there a nicer/cleaner approach?

I assume you "own" the controller? If so, I'd serialize and deserialize the list as a comma separated string on each side. It'd also be nice if criteria.JobTypes is an empty list instead of a possible null, then you don't need the ?? below.

var redirectUrl = Url.Action("search", new {
// ...
jobTypes = String.Join(criteria.JobTypes ?? new string[0], ",")
}


And do jobTypes.split(",") in the action.

URL would look a bit nicer too:

/search?q=developer&advanced=false&salaryfrom=20000&salaryto=80000&jobTypes=Full%20Time,Contract


To expand on Lars-Erik's answer, you can also use the other overload, the one that takes a dictionary.
This is also useful to construct e.g. an input that might or might not be disabled.

RouteValueDictionary args = new RouteValueDictionary {
{"q", criteria.Q},
{"salaryfrom", criteria.SalaryFrom},
{"salaryto", criteria.SalaryTo},
};
if(criteria.JobTypes != null) {
// Either foreach the jobTypes or go Lars-Erik's way (nicer).
}


Take care about special characters!
If you don't fully control the input, you might get a jobType "R&D" that will break your url: /search?q=...&jobTypes=R&D gets you jobTypes=R.

You can add the array elements individually to the RouteValueDictionary -- you just have to change the name to match the model binding name for round trip purposes.

The second argument to your action can be a RouteValueDictionary as ANeves said.

RouteValueDictionary rvd = new RouteValueDictionary { { "name", "value"}, ...};
int i = 0;
criteria.JobTypes.ForEach(v => rvd.Add(String.Format("jobTypes[{0}]", i++), (object) v));


Instead of Type Casting to 'objectorobject[]or usingRouteValueDictionary. A simple way to achieve the same is using “Newtonsoft.Json”

If using .Net Core 3.0 or later;

Default to using the built in System.Text.Json parser implementation.

@using System.Text.Json;

…….

@Url.Action(“ActionName”, “ControllerName”, new {object = JsonConvert.SerializeObject(‘@ModalObject’)  }))



If stuck using .Net Core 2.2 or earlier;

Default to using Newtonsoft JSON.Net as your first choice JSON Parser.

@using Newtonsoft.Json;

…..

@Url.Action(“ActionName”, “ControllerName”, new {object = JsonConvert.SerializeObject(‘@ModalObject’)  }))


you may need to install the package first.

PM> Install-Package Newtonsoft.Json


Then,

public ActionResult ActionName(string modalObjectJSON)
{
Modal modalObj = new Modal();
modalObj = JsonConvert.DeserializeObject<Modal>(modalObjectJSON);

}
`