2011-09-29 51 views
0

我正在構建一個MVC應用程序,該應用程序由兩個不同的唯一ID引用的實體組成,一個醜陋的系統生成的ID和一個更加用戶友好的5個字符的「短代碼」。例如,我想我的最終用戶能夠在瀏覽器中輸入以下網址的:ASP.Net MVC3:設置路由處理多個唯一的ID?

http://intranet/PRJ2011004

http://intranet/DEP42

同樣,兩種編碼是唯一的。我已經正確設置了第一個URL的路由。當用戶輸入該URL時,他們會收到顯示實體索引頁面的適當頁面:PRJ201104。

如何設置處理第二種情況的路線?優選地,有一種方法可以「誘使」MVC將其從短代碼傳遞給項目的控制器的值更改爲項目。

我想要一種方法來攔截5個字符的短代碼路由,獲取提供的值並在我的實體表中查找它,然後如果我找到匹配的記錄,我想要(按優先順序):

  1. 顯示實體的索引頁,同時仍保留url中的短代碼。在這種情況下,我想「欺騙」處理路由的控制器,認爲傳入的「id」實際上是唯一的ID而不是短碼(爲了不必重構我現有的代碼)
  2. Re - 將網址指向具有工作唯一(醜陋)ID的網址。

如果我沒有找到匹配的實體使用該短代碼值,我會讓我的標準路由處理繼續(例如,我的「錯誤」和「管理員」控制器,這兩個都是5個字符而不是短代碼,將繼續適當工作)。

TIA

回答

0

自定義路線可以做的工作:

public class MyRoute : Route 
{ 
    public MyRoute(string url, object defaults) 
     : base(url, new RouteValueDictionary(defaults), new MvcRouteHandler()) 
    { } 

    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
     var rd = base.GetRouteData(httpContext); 
     var id = rd.Values["id"] as string; 
     if (id == null) 
     { 
      return rd; 
     } 

     // TODO: if you think that the id provided is a pretty id 
     // query the database to fetch the other id 

     if (IsPrettyId(id)) 
     { 
      id = FetchCorrespondingId(id); 
      rd.Values["id"] = id; 
     } 
     return rd; 
    } 
} 

,然後註冊此自定義路線:

public static void RegisterRoutes(RouteCollection routes) 
{ 
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
    routes.Add(
     "Default", 
     new MyRoute(
      "{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
     ) 
    ); 
} 

現在控制器動作裏面,你會總是有長的醜編號:

public ActionResult Index(string id) 
{ 

} 
+0

我認爲這很接近。 URL:http:// intranet/ABCDE正確解析。但是現在,url http:// intranet/Dashboard沒有。有沒有辦法給自定義路由添加約束,以便它只通過正則表達式匹配來選擇作品? – lamarant

+0

@Leon,當然,只需要使用帶有約束的Route構造函數的另一個重載。 –

+0

有關如何實現該過載的一點幫助嗎?我無法弄清楚正確的語法。很近。 – lamarant