使用 Slug 的 C# Mvc 通用路由
C# Mvc Generic Route using Slug
我正在尝试创建一个通用路由来处理 slug,但我总是遇到错误
我的想法是,而不是 www.site。com/controller/action 我得到 url 一个友好的 www.site.com/{鼻涕虫}
例如www.site.com/Home/Open 将改为 www.site.com/open-your-company
错误
server error in '/' application The Resource cannot be found
在我的Global.asax我有
public static void RegisterRoutes(RouteCollection routes)
{
//routes.Clear();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("DefaultSlug", "{slug}", new { controller = "Home", action = "Open", slug = "" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
area = "",
controller = "Home",
action = "Index",
id = UrlParameter.Optional,
slug = ""
}
);
}
在我的 cshtml
之一中,我有以下 link (即使它被评论,仍然有同样的错误)。
@Html.ActionLink("Open your company", "DefaultSlug", new { controller = "Home", action = "Open", slug = "open-your-company" })
编辑:家庭控制器
public ActionResult Open() {
return View(new HomeModel());
}
在Global.asax中你slug
不能为空,如果为空则url不会走默认路由
public static void RegisterRoutes(RouteCollection routes)
{
//routes.Clear();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "DefaultSlug",
url: "{slug}",
defaults: new { controller = "Home", action = "Open" },
constraints: new{ slug=".+"});
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
area = "",
controller = "Home",
action = "Index",
id = UrlParameter.Optional
}
);
}
并更新 HomeController
public ActionResult Open(string slug) {
HomeModel model = contentRepository.GetBySlug(slug);
return View(model);
}
测试路线link...
@Html.RouteLink("Open your company", routeName: "DefaultSlug", routeValues: new { controller = "Home", action = "Open", slug = "open-your-company" })
和行动link...
@Html.ActionLink("Open your company", "Open", routeValues: new { controller = "Home", action = "Open", slug = "open-your-company" })
两者都产生...
http://localhost:35979/open-your-company
这是我完成类似任务所采取的步骤。这依赖于模型上的自定义 Slug
字段来匹配路线。
设置您的控制器,例如Controllers\PagesController.cs:
public class PagesController : Controller
{
// Regular ID-based routing
[Route("pages/{id}")]
public ActionResult Detail(int? id)
{
if(id == null)
{
return new HttpNotFoundResult();
}
var model = myContext.Pages.Single(x => x.Id == id);
if(model == null)
{
return new HttpNotFoundResult();
}
ViewBag.Title = model.Title;
return View(model);
}
// Slug-based routing - reuse View from above controller.
public ActionResult DetailSlug (string slug)
{
var model = MyDbContext.Pages.SingleOrDefault(x => x.Slug == slug);
if(model == null)
{
return new HttpNotFoundResult();
}
ViewBag.Title = model.Title;
return View("Detail", model);
}
}
在App_Start\RouteConfig.cs中设置路由
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
// Existing route register code
// Custom route - top priority
routes.MapRoute(
name: "PageSlug",
url: "{slug}",
defaults: new { controller = "Pages", action = "DetailSlug" },
constraints: new {
slug = ".+", // Passthru for no slug (goes to home page)
slugMatch = new PageSlugMatch() // Custom constraint
}
);
}
// Default MVC route setup & other custom routes
}
}
自定义 IRouteConstraint 实现,例如Utils\RouteConstraints.cs
public class PageSlugMatch : IRouteConstraint
{
private readonly MyDbContext MyDbContext = new MyDbContext();
public bool Match(
HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection
)
{
var routeSlug = values.ContainsKey("slug") ? (string)values["slug"] : "";
bool slugMatch = false;
if (!string.IsNullOrEmpty(routeSlug))
{
slugMatch = MyDbContext.Pages.Where(x => x.Slug == routeSlug).Any();
}
return slugMatch;
}
}
我正在尝试创建一个通用路由来处理 slug,但我总是遇到错误
我的想法是,而不是 www.site。com/controller/action 我得到 url 一个友好的 www.site.com/{鼻涕虫}
例如www.site.com/Home/Open 将改为 www.site.com/open-your-company
错误
server error in '/' application The Resource cannot be found
在我的Global.asax我有
public static void RegisterRoutes(RouteCollection routes)
{
//routes.Clear();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("DefaultSlug", "{slug}", new { controller = "Home", action = "Open", slug = "" });
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
area = "",
controller = "Home",
action = "Index",
id = UrlParameter.Optional,
slug = ""
}
);
}
在我的 cshtml
之一中,我有以下 link (即使它被评论,仍然有同样的错误)。
@Html.ActionLink("Open your company", "DefaultSlug", new { controller = "Home", action = "Open", slug = "open-your-company" })
编辑:家庭控制器
public ActionResult Open() {
return View(new HomeModel());
}
在Global.asax中你slug
不能为空,如果为空则url不会走默认路由
public static void RegisterRoutes(RouteCollection routes)
{
//routes.Clear();
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "DefaultSlug",
url: "{slug}",
defaults: new { controller = "Home", action = "Open" },
constraints: new{ slug=".+"});
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new
{
area = "",
controller = "Home",
action = "Index",
id = UrlParameter.Optional
}
);
}
并更新 HomeController
public ActionResult Open(string slug) {
HomeModel model = contentRepository.GetBySlug(slug);
return View(model);
}
测试路线link...
@Html.RouteLink("Open your company", routeName: "DefaultSlug", routeValues: new { controller = "Home", action = "Open", slug = "open-your-company" })
和行动link...
@Html.ActionLink("Open your company", "Open", routeValues: new { controller = "Home", action = "Open", slug = "open-your-company" })
两者都产生...
http://localhost:35979/open-your-company
这是我完成类似任务所采取的步骤。这依赖于模型上的自定义 Slug
字段来匹配路线。
设置您的控制器,例如Controllers\PagesController.cs:
public class PagesController : Controller { // Regular ID-based routing [Route("pages/{id}")] public ActionResult Detail(int? id) { if(id == null) { return new HttpNotFoundResult(); } var model = myContext.Pages.Single(x => x.Id == id); if(model == null) { return new HttpNotFoundResult(); } ViewBag.Title = model.Title; return View(model); } // Slug-based routing - reuse View from above controller. public ActionResult DetailSlug (string slug) { var model = MyDbContext.Pages.SingleOrDefault(x => x.Slug == slug); if(model == null) { return new HttpNotFoundResult(); } ViewBag.Title = model.Title; return View("Detail", model); } }
在App_Start\RouteConfig.cs中设置路由
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { // Existing route register code // Custom route - top priority routes.MapRoute( name: "PageSlug", url: "{slug}", defaults: new { controller = "Pages", action = "DetailSlug" }, constraints: new { slug = ".+", // Passthru for no slug (goes to home page) slugMatch = new PageSlugMatch() // Custom constraint } ); } // Default MVC route setup & other custom routes } }
自定义 IRouteConstraint 实现,例如Utils\RouteConstraints.cs
public class PageSlugMatch : IRouteConstraint { private readonly MyDbContext MyDbContext = new MyDbContext(); public bool Match( HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection ) { var routeSlug = values.ContainsKey("slug") ? (string)values["slug"] : ""; bool slugMatch = false; if (!string.IsNullOrEmpty(routeSlug)) { slugMatch = MyDbContext.Pages.Where(x => x.Slug == routeSlug).Any(); } return slugMatch; } }