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,
A URL action is a hyperlink that points to a web page, file, or other web-based resource outside of Tableau. You can use URL actions to create an email or link to additional information about your data.
You can convert the model into an JSON object by using the the build-in JSON-helper,like this: $(this). load('@Url. Action("CreatePartial")',@Html.
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)
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);
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With