我试图创建一个使用slugs的通用路由,但我总是遇到错误
我的想法是,而不是 www.site.com/controller/action ,我会在网址中找到友好的 www.site.com/ {slug}
e.g。 www.site.com/Home/Open 将改为 www.site.com/open-your-company
错误
服务器错误' /'应用程序无法找到资源
在 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
中,我有以下链接(即使在评论时,仍然存在相同的错误)。
@Html.ActionLink("Open your company", "DefaultSlug", new { controller = "Home", action = "Open", slug = "open-your-company" })
编辑:HomeController
public ActionResult Open() {
return View(new HomeModel());
}
答案 0 :(得分:0)
在Global.asax中,slug
不能为空,如果为空,则网址不会转到默认路由
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);
}
测试路线链接......
@Html.RouteLink("Open your company", routeName: "DefaultSlug", routeValues: new { controller = "Home", action = "Open", slug = "open-your-company" })
和行动链接......
@Html.ActionLink("Open your company", "Open", routeValues: new { controller = "Home", action = "Open", slug = "open-your-company" })
都产生......
http://localhost:35979/open-your-company
答案 1 :(得分:0)
这是我完成类似任务所采取的步骤。这取决于模型上的自定义Slug
字段以匹配路径。
设置您的控制器,例如控制器\ 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;
}
}