2012-02-16 70 views
1

之間的區別我的網站,我建立鏈接動態從xml(-nodes)。恰巧,大部分的時間,產品詳細的鏈接建立這樣的:MVC3路線對照參數

me.com/one/two/three/four/productdetail

也有一些情況,雖然那裏是第五第四,所以鏈路之後節點是:

me.com/one/two/three/four/five/productdetail

我怎樣才能在我的操作方法,從區分該第五「段」 productdetail如果他們都是字符串?

公共的ActionResult產品(串之一,串2,串3,串中的四個,串產品詳情,弦五= NULL) { }

我現在有這樣的定義的路由:

{控制器} {{action}/{one}/{two}/{three}/{four}/{productdetail}

{controller}/{action}/{one}/{two}/{three}/{四}/{五}/{productdetail}

(其中{one}至{five} ar e UrlParameter.Optional)

使用正則表達式的路由約束似乎沒有幫助,因爲它們都是字符串(甚至它們都可以是非常相似的字符串)。

這甚至有可能嗎?

+0

剛纔兩條路線怎麼了?這應該工作得很好 – AaronHS 2012-02-16 11:04:20

+0

亞倫,然後它將me.com/one/two/three/four/five/的鏈接映射到me.com/one/two/three/four/productdetail ... – stefjnl 2012-02-16 11:07:20

+0

我編輯了我的回答,但基本上,如果兩種模式相同,那麼框架無法區分路線。你需要使用一個約束來區分這個 – AaronHS 2012-02-16 11:10:51

回答

0

通過有兩個單獨的路線,一個具有五個元素,另一個具有四個元素,這些路線可以只是去同一個地方。一個經過{5}另一個不經過。

編輯:如果兩種模式是相同的,那麼唯一的辦法是使用約束來區分不同的值。

+0

亞倫,謝謝你的回答。所以說,如果我有一個名爲「phone1」的productdetail,而且還有一個叫做「phone1」的第五個分段,那麼沒有辦法區分這些路線嗎? (正則表達式對此似乎無用)。那麼我必須採取另一種方法。這肯定是MVC3框架的一個陷阱,然後...... – stefjnl 2012-02-16 11:20:15

+0

不用擔心。爲了回答你的問題,把自己放在框架鞋。框架如何知道將您的請求指向哪裏?如果url模式相同,那麼框架就不知道要選擇哪條路線。可能考慮關於洗牌你的網址,或尋找一種方法來限制工作 – AaronHS 2012-02-16 11:28:05

0

我認爲你可以對路由聲明進行一些更改以滿足你的期望。

  1. 不要把1到5作爲可選參數。
  2. MapRoot {controller}/{action}/{one}/{two}/{three}/{four}/{five}/{productdetail}應該早於{controller}/{一個}/{two}/{three}/{four}/{productdetail}
  3. 後面跟着默認的maproute。 {控制器}/{行動}/{ID} ID爲可選

現在

  1. 申請me.com/one/two/three/four/five/productdetail將匹配 僅限第一條路線。
  2. 請求me.com/one/two/three/four/productdetail僅匹配 第二條路線。
+0

嗨瑪納斯,這將工作,但我也需要能夠去 me.com/one/two/three/four/five/以顯示產品詳細清單。編輯:我會嘗試沒有可選參數 – stefjnl 2012-02-16 12:10:05

+0

編輯2:沒有可選參數theres沒有匹配me.com/one/two/ – stefjnl 2012-02-16 12:16:38

0

如果你的情況不能設置路由約束,那麼你最好的選擇是改變你的路由,這樣ASP.NET MVC就可以知道你的產品細節參數是爲了避免與選項{5}混淆。

把產品詳細的,可在一個至五個值永遠不會發生,例如某些特定字符串的前面:

{controller}/{action}/{one}/{two}/{three}/{four}/p/{productdetail} 

{controller}/{action}/{one}/{two}/{three}/{four}/{five}/p/{productdetail} 

這將解決您的問題。

1

解決這個問題的最簡單方法是爲5,4,3和2參數註冊路由。按順序註冊它們。

{controller}/{one}/{two}/{three}/{four}/{five}/{productdetail} 
{controller}/{one}/{two}/{three}/{four}/{productdetail} 
{controller}/{one}/{two}/{three}/{productdetail} 
{controller}/{one}/{two}/{productdetail} 

你不能註冊{}控制器路由/ {一個}/{}產品詳情,而無需創建一個路由約束,以確保{}一個不{}控制器的行動。

我強烈建議,如果你有什麼選項列表1 - 5可以是你創建一個自定義路由約束,將驗證他們,所以你不意外地匹配你不打算,但你應該的路線與我已經佈置的上述路線保持安全。

創建IRouteConstraint並不困難。下面是一些代碼,我以前使用了一個路由約束,它允許從一個特定的控制器調用一個動作而不需要指定控制器。一個例子是一個名爲Home的控制器,其中有一個「關於」的動作,這個約束允許你調用/ about而不是/ home/about。

這與您要執行的操作相關,因爲它會告訴您如何進行一些驗證,以便在需要時區分{one}和{action}。

路線約束:

routes.MapRoute(
      "Home", 
      "{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 
      new { IsRootAction = new CAA.Utility.Constraints.IsRootActionConstraint() } // Route Constraint 
     ); 


     routes.MapRoute(
      "Default", // Route name 
      "{controller}/{action}/{id}", // URL with parameters 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ); 

在你的情況,驗證該{}一個不匹配的路由:

public class IsRootActionConstraint : IRouteConstraint 
{ 
    private List<string> _actions; 

    public IsRootActionConstraint(): this("homecontroller") 
    { 

    } 
    public IsRootActionConstraint(string ControllerName) 
    { 
     Type _type = Assembly 
          .GetCallingAssembly() 
          .GetTypes() 
          .Where(type => type.IsSubclassOf(typeof(Controller)) && type.Name.ToLower() == ControllerName.ToLower()) 
          .SingleOrDefault(); 
     if (_type != null) 
     { 
      _actions = (from methods in _type.GetMethods() where typeof(ActionResult).IsAssignableFrom(methods.ReturnType) select methods.Name.ToLower()).ToList(); 
     } 
    } 

    #region IRouteConstraint Members 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     return _actions.Contains((values["action"] as string).ToLower()); 
    } 

    #endregion 
} 

而當你在Global.asax註冊您的路線{控制器}不應該太難。您可以將反射代碼移入Match方法,並使用控制器的路由值中的名稱查找操作。

+0

我不知道這是如何解決OP的問題。他有兩個相同的模式。您列出的模式都有不同的參數計數,這是不正確的。 – AaronHS 2012-02-18 05:30:07

+0

OP有不同數量的產品屬性(1 - 5)的問題。他有一些工作可以讓四個屬性,但不是五分之一。通過按特定順序(5路線,4路線,3路線,2路線)設置路線,您可以允許多達5個參數。雖然我的路線缺少行動(我一定是在看別人的路線列表而不是OP),但這個概念仍然適用。如果行爲出現在路由中,我的某些路由約束不適用,但是如何創建路由約束並進行匹配的概念仍然存在。 – 2012-02-19 17:51:50

+0

IRouteConstraint可以對路由集合中的任何參數進行條件檢查,以查看IF是否匹配。這將是IRouteConstraint可以分辨出{five}和{productdetail}之間的區別,但是您必須在Match方法中進行一些數據庫驗證。 – 2012-02-19 17:54:21