2012-12-07 130 views
0

我在我的MVC 4项目中有这个简单的用户AreaMVC ActionLink触发RouteConstraint?

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" } 
      ); 
    } 
} 

为了确保用户名存在,我有一个名为RouteConstraintUserNameRouteConstraint()

这一切都在我的用户表一个简单的查找,如果用户已经发现返回true。

到目前为止好,这个建设工作正常!

现在;我在用户Area视图具有代码

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

以下行此单行导致被称为UserNameRouteConstraint() ....

如何以及为什么!?如果我用普通的HTML编写链接(请参见下面的示例),它可以很好地工作,但我希望尽可能接近MVC原则。

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

有没有办法阻止RouteConstraint的调用?

+0

你正在为{userName}传递“username”。它将需要名称为“用户名”的用户存在。它提供了什么? –

回答

1

每当生成路由时,都会处理约束。

您可以添加此检查根据约束是否处理传入的请求或者从一个函数生成一个URL像ActionLink停止约束:

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

    ... 
} 
+0

太棒了!是的,这是诀窍。谢谢! – 321X

0

当你调用ActionLink幕后它创建了一个RouteValueDictionary并运行RouteCollection.GetVirtualPath()。这部分不是开源的,但我最好猜测它是如何工作的,它检查生成的路由值字典的参数与每个路由的默认值和约束,直到找到匹配的路由值。正因为如此,它会运行你的约束条件,并且你应该让它运行你的约束,以便它不会匹配到错误的路线。