假设我有三个实体:Events
,People
和Pictures
,Events
还有一个slug属性来美化我的网址。
我想通过slug路由事件,并显式路由所有其他实体。另外,我不想要默认路由。
事件控制器被映射三次。使用slug获取现有事件,没有站点索引页面的参数以及其他操作,因此我可以执行Create(例如,当时没有slug)。
考虑到这一点,我的地图如下:
routes.MapRoute(
name: "Profiles",
url: "Profile/{userName}/{action}",
defaults: new { controller = "Profile", action = "Index",
userName = UrlParameter.Optional });
routes.MapRoute(
name: "Pictures",
url: "Picture/{action}/{id}",
defaults: new { controller = "Picture", action = "Index",
id = UrlParameter.Optional });
routes.MapRoute(
name: "EventBySlug",
url: "{slug}/{action}",
defaults: new { controller = "Event", action = "Details"} );
routes.MapRoute(
name: "Events",
url: "Event/{action}",
defaults: new { controller = "Event", action = "Index",
id = UrlParameter.Optional } );
routes.MapRoute(
name: "Default",
url: "",
defaults: new { controller = "Event", action = "Index" } );
这很好,直到我为主页面(在我的布局中)创建一个ActionLink
@Html.ActionLink("Home", "Index", "Events")
如果我在观看活动/christmass-2013
时点击了主页链接,我会转到/christmass-2013/Index
。此外,如果我从新索引执行搜索,则新网址为/christmass-2013/Index?filter=Summer2014
如何配置它以便我不留下任何痕迹?
答案 0 :(得分:2)
由于处理顺序和匹配路线您不希望它们匹配,路线定义可能很挑剔。我从零开始创建了一个MVC应用程序,并且能够让您的路由正常工作,并且实际上能够删除一个。首先是代码,然后是解释:
routes.MapRoute(
name: "Profiles",
url: "Profile/{userName}/{action}",
defaults: new
{
controller = "Profile",
action = "Index",
userName = UrlParameter.Optional
});
routes.MapRoute(
name: "Pictures",
url: "Picture/{action}/{id}",
defaults: new
{
controller = "Picture",
action = "Index",
id = UrlParameter.Optional
});
routes.MapRoute(
name: "Events",
url: "{controller}/{action}",
defaults: new { controller = "Event", action = "Index"},
constraints: new { controller = "Event" });
routes.MapRoute(
name: "EventBySlug",
url: "{slug}",
defaults: new { controller = "Event", action = "Details" });
首先,由于您的第四条和第五条路线基本相同(没有URL),我们能够将这些路线组合到我的第三条路线中。其次,我们需要你的slug路由只在没有其他路由匹配时被调用,所以我们将它移动到最后一个路由(这会处理你提到的路径)。最后,由于我的路径3和4都可能被调用(我们如何知道它是slug还是控制器),还有第四个参数基本上限制了“Controller”的值。我不知道你是否有任何其他控制器在Event,Profile,Picture之外,这假设你没有。由于Profile和Picture已经映射到以前的路径中,因此我们不必在此处约束它们。但是,如果您有一个帮助控制器或类似的东西,您需要更新我的第三条路线
routes.MapRoute(
name: "Events",
url: "{controller}/{action}",
defaults: new { controller = "Event", action = "Index"},
constraints: new { controller = "Event|Help" });
将|
运算符用作"OR"
- controller must equal Event Or Help
。
谨慎的话。一,确保slug永远不会是控制器的名称,否则slug会尝试映射到控制器/动作而不是细节。第二,如果通过slug进行路由,请确保它们在您的系统中是唯一的,否则您可能会提取错误的数据。
修改强>
看来这个路由配置也适用于我(没有约束)
routes.MapRoute(
name: "EventBySlug",
url: "{slug}",
defaults: new { controller = "Event", action = "Details" });
routes.MapRoute(
name: "Events",
url: "{controller}/{action}",
defaults: new { controller = "Event", action = "Index"});
在索引页面上:
@Html.ActionLink("Christmas 2013!", "Details", new {controller="Event", slug="Christmas-2013"})
返回网址:http://localhost:11319/Christmas-2013
我的活动详情页面:@Html.ActionLink("Home", "Index", "Event")
返回网址:http://localhost:11319/
所以基本上我已经确定有几种可能的方法来实现这一目标。这实际上取决于您的其他一些URL的复杂程度。