What if I need to pass values collection? For example:
<a href="@Url.Action(...., new { Values = new [] { "Foo", "Bar" } })"
Is this possible with asp-all-route-data?
I think it can be IDictionary<string,object> or RouteValueDictionary instead of IDictionary<string,string>.
I can't use anonymous class because keys must be with dot in my case. Example: FooFilter.Values.
Anonymous class declaration will produce compilation error:
<a href="@Url.Action(...., new { FooFilter.Values = new [] { "Foo", "Bar" } })"
and asp-all-route-data can't be used because it must be IDictionary<string,string>.
I found only one solution:
<a href="@Url.Action(...)?FooFilter.Values=Foo&FooFilter.Values=Bar"
and this solution is horrible....
Is there a reason you don't use RouteValueDictionary then?
This Ok:
<a href="@Url.Action("List", "FooController", new RouteValueDictionary { {"area", "FooArea"}, {"FooFilter.Values", new[]{"StatusA", "StatusB"}} })">
But it can't be used for asp-all-route-data. And changing type of asp-all-route-data to IDictionary<string,object> couses problems with legacy code. So ASP-team will not agree to such changes I suppose...
If asp-all-route-data was IDictionary<string,object> then code will be more nice:
<a asp-action="FooAction" asp-route-status="@(new[]{ "StatusA", "StatusB" })"
the asp-route-data is an IDictionary
IMHO I think the real question that only you can answer is routing/uri the correct way to go about this ? or should the data be passed in a http post body that allows for transfer of structured/hyracical data? unlike URIs without custom encoding
https://en.m.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax
If you look at the implementaion of AnchorTagHelper then you will see that _routeValues is passing to RouteValueDictionary contructor. That's all. There is no special handling. And RouteValueDictionary is IDictionary<string,object>!
RouteValueDictionary routeValues = null;
if (_routeValues != null && _routeValues.Count > 0)
{
routeValues = new RouteValueDictionary(_routeValues);
}
and then
tagBuilder = Generator.GenerateActionLink(.... routeValues: routeValues, ...);
@grahamehorner Why you say this is a problem for AnchorTagHelper.RouteValues but isn't for RouteValueDictionary? Problematic is one.
@Remleo yes your correct; however the RouteValueDictionary not just for creating URI links; and the boxing/unboxing the is performed at a low level by the appropriate urlHelper; by using a IDictionary
@grahamehorner In my view, the tag helpers are replacements of IUrlHelper's extensions. In Url.Action(...) I can use code like this: new { FooFilter = new [] { "Foo", "Bar" } }, but in asp-route-* I can't. And it is a bit confusing. This synthetic constraint is illogical as for me.
In my project I'm added own TagHelper with n-route-* property with type IDictionary<string,object> and yet no problems. In what cases it can cause problems?
@NTaylorMullen, are you aware of any scenarios, where the tag helper introduced by @Remleo can cause issues?
In what cases it can cause problems?
If you're looking to provide a string value for your route value you will end up having issues. You'll need to save your string value to a variable before setting it to the attribute.
This method is using asp-all-route-data:
@{
IDictionary<string, string> routeData = new Dictionary<string, string>();
routeData.Add("data1", "12345");
routeData.Add("data2", "67890");
}
<a asp-controller="Home" asp-action="About" asp-all-route-data="routeData">Test Route Data</a>
Or in this way:
@{
IDictionary<string, string> routeData = new Dictionary<string, string>
{
{"data1", "12345"},
{"data2", "67890"}
};
}
<li><a asp-controller="Home" asp-action="About" asp-all-route-data="routeData">Test Route Data</a></li>
You can also place the variable with "@" or without it in asp-all-route-data.
https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.taghelpers.anchortaghelper.routevalues
@MRT-77 have you read my first comment? Your example is too simple. What if I need to pass collection as value?
@NTaylorMullen Why do you see the problems in AnchorTagHelper.RouteValues but not in the RouteValueDictionary? AnchorTagHelper just uses RouteValueDictionary inside.
@NTaylorMullen Why do you see the problems in AnchorTagHelper.RouteValues but not in the RouteValueDictionary? AnchorTagHelper just uses RouteValueDictionary inside.
It's an artifact of how the TagHelper system tries to associate HTML with the AnchorTagHelper.RouteValues property. Going to deep dive a bit here but hopefully it helps understand the problem.
When you write:
@{
IDictionary<string, string> routeData = new Dictionary<string, string>();
}
<a asp-controller="Home" asp-all-route-data="routeData">...</a>
<a asp-controller="Home" asp-route-foo="something">...</a>
Behind the scenes Razor generates something like:
```C#
IDictionary
tagHelper = new AnchorTagHelper();
tagHelper.Controller = "Home";
tagHelper.RouteValues = routeData;
Write(tagHelper);
tagHelper = new AnchorTagHelper();
tagHelper.Controller = "Home";
tagHelper.RouteValues["foo"] = "something";
Razor does this because it has a special understanding of `Dictionary<string, TType>`. When a TagHelper has a `Dictionary<string, TType>` the system enables users to add single entries into that dictionary or set the entire thing (as shown by the example above). Now imagine if `RouteValues` was exposed as `Dictionary<string, object>`; in that world the TagHelper system allows users to provide anything other than strings. For example:
@{
var something = true;
}
would result in:
```C#
tagHelper = new MyTaghelperThatTakesStringObject();
tagHelper.Foo["key"] = something;
Note the lacking quotations around something. Basically, since HTML uses quotations to surround their attribute values but those quotations are also significant in a C# landscape we chose to have the route data represented as the most common case: a user doing string->string route key->values.
As a total side note, it would technically be possible to provide a
This seems to be a duplicate of closed issue #7826
We periodically close 'discussion' issues that have not been updated in a long period of time.
We apologize if this causes any inconvenience. We ask that if you are still encountering an issue, please log a new issue with updated information and we will investigate.