简体   繁体   中英

MVC ActionLink triggers a RouteConstraint?

I have this simple User Area in my MVC 4 project.

public class UserAreaRegistration : AreaRegistration
{
    public override string AreaName { get { return "User"; } }

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute("User_Constraint",
                "{userName}/{controller}/{action}/{id}",
                new { userName = string.Empty, controller = "Products", action = "Index", id = UrlParameter.Optional },
                new { userName = new UserNameRouteConstraint() },
                new[] { "T2b.Web.Areas.User.Controllers" }
            );
    }
}

To make sure the User Name exists I have a RouteConstraint called UserNameRouteConstraint()

All this does is a simple lookup in my users table and return true if the user has been found.

So far so good, this construction works fine!

Now; My view in the User Area has the following line of code

@Html.ActionLink("More information", "details", new {id = product.Guid})

This single line causes the UserNameRouteConstraint() to be called....

How and why!? If I write the link in plain HTML (see example below) it works well, but I want to keep to the MVC Principles as close as possible.

<a href="/username/Products/details/@product.Guid">More information</a>

Is there any way to prevent the RouteConstraint call?

Whenever routes are generated the constraints are processed.

You can add this check to stop the constraint depending on whether the constraint is handling an incoming request or generating a URL from a function like ActionLink :

public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
    if(routeDirection == RouteDirection.UrlGeneration)
        return false;

    ...
}

When you call ActionLink behind the scenes it creates a RouteValueDictionary and runs RouteCollection.GetVirtualPath() . This part is not open source but my best guess as to how it works is that it checks the parameters of the generated route value dictionary against the defaults and constraints of each route until it finds one that matches. Because of this it runs your constraints, and you should want it to run your constraints so that it doesn't end up matching to the wrong route.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM