aspnetcore: Url.Action doesn't respect constraints from IApplicationModelConvention
Describe the bug
I implemented localized routes using a ApplicationModelConvention.
This works fine as long as I type the urls directly in the browser.
So, for example, german routes are only allowed in german culture. and routes from other languages are returning a 404. Exactly as expected.
But when I use Url.Action it doesn’t respect the constraints. so for example if i’m on the english domain i get russian links (depending on the order they are inserted)
What am I doing wrong?
services.AddMvc(o =>
{
o.Conventions.Insert(0, new LocalizedRouteConvention());
})
public class LocalizedRouteConvention : IApplicationModelConvention
{
public void Apply(ApplicationModel application)
{
foreach (var controller in application.Controllers)
{
foreach (var action in controller.Actions)
{
var attributes = action.Attributes.OfType<RouteAttribute>().ToArray();
if (!attributes.Any()) return;
foreach (var attribute in attributes)
{
SelectorModel defaultSelector = action.Selectors.First();
foreach (var localizedVersion in GetLocalized(attribute.Template))
{
if (!action.Selectors.Any(s => s.AttributeRouteModel.Template == localizedVersion.Template))
{
action.Selectors.Insert(0, new SelectorModel(defaultSelector)
{
AttributeRouteModel = localizedVersion,
ActionConstraints =
{
new CultureActionConstraint { Culture = ((LocalizedRouteAttribute) localizedVersion.Attribute).Culture }
}
});
}
}
}
}
}
}
}
And here the constraint
public class CultureActionConstraint : IActionConstraint
{
public string Culture { get; set; }
public int Order => 0;
public bool Accept(ActionConstraintContext context)
{
return CultureInfo.CurrentCulture.TwoLetterISOLanguageName == Culture;
}
}
Expected behavior
Url.Action should also only use the routes that are allowed.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 2
- Comments: 23 (18 by maintainers)
I’ve created an issue at https://github.com/aspnet/Routing/issues/896
@cypressious @BoasE let me try my last attempt to make workaround to your issue, hope to reply ASAP
http://your-domain.com/benutzer and http://your-domain.de/user
should not be allowed
To be precise, we want
http://your-domain.com/user for en culture http://your-domain.de/benutzer for de culture
Thanks guys for reproducing the issue, I will try to investigate on this soon