Reputation: 12374
Say I have an action method:
[HttpGet]
public ActionResult Search(List<int> category){
...
}
The way the MVC model binding works, it expects a list of category like this:
/search?category=1&category=2
So my questions are:
Url.Action("Search", new {category=???}) //Expect: /search?category=1&category=2
var categories = new List<int>(){1,2}; //Expect: /search?category=1&category=2
Url.Action("Search", new {category=categories}) //does not work,
Upvotes: 12
Views: 24140
Reputation: 21
Instead Type Casting to “object” or “object[]” or using RouteValueDictionary. 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);
}
Upvotes: 1
Reputation: 28608
Build the querystring yourself, it's evident that UrlHelper was not designed for this use case.
Using:
static class QueryStringBuilder {
public static string ToQueryString(this NameValueCollection qs) {
return ToQueryString(qs, includeDelimiter: false);
}
public static string ToQueryString(this NameValueCollection qs, bool includeDelimiter) {
var sb = new StringBuilder();
for (int i = 0; i < qs.AllKeys.Length; i++) {
string key = qs.AllKeys[i];
string[] values = qs.GetValues(key);
if (values != null) {
for (int j = 0; j < values.Length; j++) {
if (sb.Length > 0)
sb.Append('&');
sb.Append(HttpUtility.UrlEncode(key))
.Append('=')
.Append(HttpUtility.UrlEncode(values[j]));
}
}
}
if (includeDelimiter && sb.Length > 0)
sb.Insert(0, '?');
return sb.ToString();
}
}
You can write this:
var parameters = new NameValueCollection {
{ "category", "1" },
{ "category", "2" }
};
var url = Url.Action("Search") + parameters.ToQueryString(includeDelimiter: true);
Upvotes: 3
Reputation: 62
It´s not the best way but you can Join the category list with your QueryString parameter name.
@Url.Action("Search", new {category = string.Join("&category=", categories)});
Upvotes: -2
Reputation: 2481
Instead of using an Anonymous Type, build a RouteValueDictionary
. Format the parameters as parameter[index]
.
@{
var categories = new List<int>() { 6, 7 };
var parameters = new RouteValueDictionary();
for (int i = 0; i < categories.Count; ++i)
{
parameters.Add("category[" + i + "]", categories[i]);
}
}
Then,
@Url.Action("Test", parameters)
Upvotes: 20