【发布时间】:2013-12-18 16:12:09
【问题描述】:
我正在创建一个 ASP.net MVC / Entity Framework 购物车来更熟悉这项技术。我想要的功能之一是基于独特 slug 的 URL,而不是将实体 ID 嵌入到 URL 中。一些例子:
- /
- /信息
- /信息/关于我们
- /信息/联系我们
- /男装
- /mens-clothing/mens-shirts
- /mens-clothing/mens-shirts/test-tshirt
slug 在所有内容类型中都是独一无二的,但例如,test-tshirt 可能出现在多个类别中:
- /mens-clothing/mens-shirts/test-tshirt
- /mens-clothing/clearance/test-tshirt
我创建了一个自定义路由,它采用路径中的最后一个 slug 并使用它来查找当前页面。
public class SlugRoute : RouteBase
{
public override RouteData GetRouteData(HttpContextBase httpContext)
{
string path = HttpContext.Current.Request.Path.TrimStart('/').TrimEnd('/');
if (string.IsNullOrEmpty(path))
path = "home";
string[] slugs = path.Split('/');
string slug = slugs[slugs.Length - 1];
CatalogPage page = Token.Instance.DB.Pages.SingleOrDefault(p => p.UrlSlug == slug);
if (page != null)
{
// Cache current page in context
HttpContext.Current.Items["CurrentPage"] = page;
// Set up route data
RouteData data = new RouteData(this, new MvcRouteHandler());
data.Values["action"] = "Index";
data.Values["id"] = page.Id;
data.DataTokens.Add("namespaces", new string[] { "MyProject.Presentation.Controllers" });
// Set controller value if specified in db, or set based on entity type
if (!string.IsNullOrEmpty(page.Controller))
data.Values["controller"] = page.Controller;
else if (page.GetUnproxiedType() == typeof(CategoryPage))
data.Values["controller"] = "Category";
else if (page.GetUnproxiedType() == typeof(ProductPage))
data.Values["controller"] = "Product";
else
data.Values["controller"] = "Content";
return data;
}
return null;
}
public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
return null;
}
}
这很好用,而且我在实现自定义逻辑和显示模板方面具有很好的灵活性(内容类型也有一个“视图”属性,因此我可以在控制器中动态设置视图)。
但是,在实现面包屑时,我有点绊脚石。快速而肮脏的方法是使用来自 URL 的路径,对路径中的每个 slug 进行查询,并忽略该页面是否实际上是该类别的子级。另一种解决方案是使用MvcSiteMapProvider 之类的东西,并在后端添加内容时构建一个 XML 树......我不确定这个特定实现的效果如何,因为它似乎非常专注于标准 {controller }/{action}/{id} 路由模式。
您使用或看到过哪些其他类型的实现?
【问题讨论】:
标签: asp.net-mvc asp.net-mvc-routing breadcrumbs mvcsitemapprovider