[英]Asp.net Mvc Route By Only Slug
我正在將ASP.NET MVC 4與C#一起使用。 我正在使用區域,它的名稱類似於“管理員”
這是我的路線配置;
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(name: "PageBySlug",
url: "{slug}",
defaults: new {controller = "Home", action = "RenderPage"},
constraints: new {slug = ".+"});
routes.MapRoute(name: "Default",
url: "{controller}/{action}/{id}",
defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional},
namespaces: new[] { "Web.Frontend.Controllers.Controllers" });
}
}
我生成了前端頁面鏈接,例如; “產品/蘋果手機”所以我想這樣稱呼他們。
但是錯誤是:代碼無法獲取控制器/動作方法。 我使用了前端頁面鏈接,例如;
@Html.ActionLink(linkItem.Title, "RenderPage", routeValues: new {controller = "Home", slug = linkItem.PageSlug})
@Html.RouteLink(linkItem.Title, routeName: "PageBySlug", routeValues: new { controller = "Home", action = "RenderPage", slug = linkItem.PageSlug })
<a href="@Url.Action("RenderPage", "Home", new {slug = linkItem.PageSlug})">@linkItem.Title</a>
<a href="@Url.RouteUrl("PageBySlug", new { controller = "Home", action = "RenderPage", slug = linkItem.PageSlug})">@linkItem.Title</a>
他們正在渲染網址鏈接,例如; http:// localhost:1231 / products / apple-iphone就像我想要的。 但是,當我單擊任何鏈接時,asp.net mvc會給我這個錯誤:
“ /”應用程序中的服務器錯誤。
無法找到該資源。
說明:HTTP404。您正在尋找的資源(或其依賴項之一)可能已被刪除,名稱更改或暫時不可用。 請查看以下網址,並確保其拼寫正確。
要求的網址:/ products / apple-iphone
版本信息:Microsoft .NET Framework版本:4.0.30319; ASP.NET版本:4.6.1069.1
這是我的控制器;
namespace Web.Frontend.Controllers
{
public class HomeController : BaseFrontendController
{
public ActionResult Index()
{
return View();
}
public ActionResult RenderPage(string slug)
{
return View();
}
}
}
那么,如何才能捕獲到像這樣的組合子段的每個鏈接請求並轉到我的編碼視圖?
問題是,當您請求products/iphone
,路由引擎不知道您是指“產品/ iphone”還是控制器“產品”以及操作方法“ iphone”。
您可以編寫自定義路由約束來解決此問題。 此約束將檢查網址的子段部分是否為有效的控制器,如果是,則將執行控制器操作。
public class SlugConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName,
RouteValueDictionary values, RouteDirection routeDirection)
{
var asm = Assembly.GetExecutingAssembly();
//Get all the controller names
var controllerTypes = (from t in asm.GetExportedTypes()
where typeof(IController).IsAssignableFrom(t)
select t.Name.Replace("Controller", ""));
var slug = values["slug"];
if (slug != null)
{
if (controllerTypes.Any(x => x.Equals(slug.ToString(),
StringComparison.OrdinalIgnoreCase)))
{
return false;
}
else
{
var c = slug.ToString().Split('/');
if (c.Any())
{
var firstPart = c[0];
if (controllerTypes.Any(x => x.Equals(firstPart,
StringComparison.OrdinalIgnoreCase)))
{
return false;
}
}
}
return true;
}
return false;
}
}
現在,當您為段塞注冊自定義路由定義時,請使用此路由約束。 確保在路由模式中使用{ *slug}
。 *
表示是任何內容(例如:“ a / b / c”)(可變數量的網址段-更像是全部捕獲)
routes.MapRoute(name: "PageBySlug",
url: "{*slug}",
defaults: new { controller = "Home", action = "RenderPage" },
constraints: new { slug = new SlugConstraint() }
, namespaces: new string[] { "Web.Frontend.Controllers.Controllers" });
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
, new string[] { "Web.Frontend.Controllers.Controllers" });
您只能提供這種類型的鏈接
<a href="@Url.RouteUrl("PageBySlug", new {slug = linkItem.PageSlug})">@linkItem.Title</a>
因為路由表使用您提供的路由名稱來查找您的路由。 因此不需要控制器名稱和操作名稱。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.