.NET MVC-4 路由與自定義 slug
我正在用 ASP.Net MVC 4 重寫一個網站項目,我發現很難設置正確的路線。url 結構不是 RESTful 或遵循控制器/操作模式 - 頁面具有以下 slug 結構。所有 slug 都保存在數據庫中。
/country /country/carmake /country/carmake/carmodel /custom-landing-page-slug /custom-landing-page-slug/subpage例子:
/italy /italy/ferrari /italy/ferrari/360 /history-of-ferrari /history-of-ferrari/enzo因為
Country和是不同的模型/實體Car Make,Car Model所以我希望有類似 CountryController、CarMakesController 和 CarModelsController 之類的東西,我可以在其中處理不同的邏輯並從中呈現適當的視圖。此外,我有自定義登錄頁面,其中可以包含一個或多個斜杠。我的第一次嘗試是有一個包羅萬象的
PagesController方法,它會在數據庫中查找 slug 並根據頁麵類型(例如CarMakesController)呼叫適當的控制器,然後執行一些邏輯並呈現視圖。然而,我從來沒有成功地“呼叫”另一個控制器並渲染適當的視圖——而且感覺不對。誰能在這裡指出我正確的方向?謝謝!
編輯:澄清:我不想要重定向 - 我想將請求委託給不同的控制器來處理邏輯和呈現視圖,具體取決於內容的類型(
Country等CarMake)。
由於您的連結看起來很相似,因此您無法在路由級別將它們分開。但這裡有個好消息:您可以編寫自定義路由處理程序而忘記典型的 ASP.NET MVC 連結解析。
首先,讓我們追加
RouteHandler到預設路由:routes.MapRoute( "Default", "{controller}/{action}/{id}", new { controller = "Default", action = "Index", id = UrlParameter.Optional } ).RouteHandler = new SlugRouteHandler();這允許您以不同的方式操作您的 URL,例如:
public class SlugRouteHandler : MvcRouteHandler { protected override IHttpHandler GetHttpHandler(RequestContext requestContext) { var url = requestContext.HttpContext.Request.Path.TrimStart('/'); if (!string.IsNullOrEmpty(url)) { PageItem page = RedirectManager.GetPageByFriendlyUrl(url); if (page != null) { FillRequest(page.ControllerName, page.ActionName ?? "GetStatic", page.ID.ToString(), requestContext); } } return base.GetHttpHandler(requestContext); } private static void FillRequest(string controller, string action, string id, RequestContext requestContext) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } requestContext.RouteData.Values["controller"] = controller; requestContext.RouteData.Values["action"] = action; requestContext.RouteData.Values["id"] = id; } }這裡需要一些解釋。
首先,您的處理程序應該派生
MvcRouteHandler自System.Web.Mvc.
PageItem代表我的數據庫結構,其中包含有關 slug 的所有必要資訊:
ContentID是內容表的外鍵。
GetStatic是動作的預設值,在我的情況下很方便。
RedirectManager是一個與數據庫一起使用的靜態類:public static class RedirectManager { public static PageItem GetPageByFriendlyUrl(string friendlyUrl) { PageItem page = null; using (var cmd = new SqlCommand()) { cmd.Connection = new SqlConnection(/*YourConnectionString*/); cmd.CommandText = "select * from FriendlyUrl where FriendlyUrl = @FriendlyUrl"; cmd.Parameters.Add("@FriendlyUrl", SqlDbType.NVarChar).Value = friendlyUrl.TrimEnd('/'); cmd.Connection.Open(); using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) { if (reader.Read()) { page = new PageItem { ID = (int) reader["Id"], ControllerName = (string) reader["ControllerName"], ActionName = (string) reader["ActionName"], FriendlyUrl = (string) reader["FriendlyUrl"], }; } } return page; } } }使用這個程式碼庫,你可以添加所有的限制、異常和奇怪的行為。
它在我的情況下有效。希望這對你有幫助。
