How to intercept a Url to dynamically change the routing

社会主义新天地 提交于 2020-01-05 08:11:32

问题


I am looking to do something like:

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 ..

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.

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.


回答1:


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;
    }
}

that will be registered like that:

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
    }
}


来源:https://stackoverflow.com/questions/26572712/how-to-intercept-a-url-to-dynamically-change-the-routing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!