2012-12-07 78 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()。這部分不是開源的,但我最好猜測它是如何工作的,它檢查生成的路由值字典的參數與每個路由的默認值和約束,直到找到匹配的路由值。正因爲如此,它會運行你的約束條件,並且你應該讓它運行你的約束,以便它不會匹配到錯誤的路線。