如何拦截的URL来动态改变路由 [英] How to intercept a Url to dynamically change the routing
问题描述
我希望做的是这样的:
有关类别中,控制器将 CategoryController
For categories where the Controller will be CategoryController
www.mysite.com/some-category
www.mysite.com/some-category/sub-category
www.mysite.com/some-category/sub-category/another //This could go on ..
问题是: www.mysite.com/some-product
需要指向一个 ProductController的
。通常这会映射到相同的控制器。
The problem is that: www.mysite.com/some-product
needs to point to a ProductController
. Normally this would map to the same controller.
所以,我怎么能拦截路由,所以我可以检查,如果该参数是一个相应类别或产品和路线。
So, how can I intercept the routing so I can check if the parameter is a Category or Product and route accordingly.
我试图避免类似 www.mysite.com/category/some-category
或 www.mysite.com/product/一些产品
,因为我觉得它会执行对SEO侧更好。当我可以拦截路由,我会转发给基于某些规则看蛞蝓每个等产品/类别。
I am trying to avoid having something like www.mysite.com/category/some-category
or www.mysite.com/product/some-product
as I feel it will perform better on the SEO side. When I can intercept the routing, I'll forward to a product / category based on some rules that look at slugs for each etc.
推荐答案
您可以编写一个自定义的路由达到这个目的:
You could write a custom route to serve this purpose:
public class CategoriesRoute: Route
{
public CategoriesRoute()
: base("{*categories}", new MvcRouteHandler())
{
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var rd = base.GetRouteData(httpContext);
if (rd == null)
{
return null;
}
string categories = rd.Values["categories"] as string;
if (string.IsNullOrEmpty(categories) || !categories.StartsWith("some-", StringComparison.InvariantCultureIgnoreCase))
{
// The url doesn't start with some- as per our requirement =>
// we have no match for this route
return null;
}
string[] parts = categories.Split('/');
// for each of the parts go hit your categoryService to determine whether
// this is a category slug or something else and return accordingly
if (!AreValidCategories(parts))
{
// The AreValidCategories custom method indicated that the route contained
// some parts which are not categories => we have no match for this route
return null;
}
// At this stage we know that all the parts of the url are valid categories =>
// we have a match for this route and we can pass the categories to the action
rd.Values["controller"] = "Category";
rd.Values["action"] = "Index";
rd.Values["categories"] = parts;
return rd;
}
}
这将注册这样的:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add("CategoriesRoute", new CategoriesRoute());
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
然后你就可以有相应的控制器:
and then you can have the corresponding controller:
public class CategoryController: Controller
{
public ActionResult Index(string[] categories)
{
... The categories action argument will contain a list of the provided categories
in the url
}
}
这篇关于如何拦截的URL来动态改变路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!