2014-10-26 5 views
1

Я ищу, чтобы сделать что-то вроде:Как перехватить Url динамически изменять маршрутизацию

Для категорий, где контроллер будет 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 необходимо указать a ProductController. Обычно это относится к одному контроллеру.

Итак, как я могу перехватить маршрутизацию, чтобы я мог проверить, соответствует ли этот параметр категории или продукту и маршрут.

Я стараюсь избегать чего-то вроде www.mysite.com/category/some-category или www.mysite.com/product/some-product, поскольку я чувствую, что он будет лучше работать на стороне SEO. Когда я могу перехватить маршрутизацию, я вперед к продукту/категории на основе некоторых правил, которые смотрят на слизней для каждого и т.д.

+0

Как вы ожидаете различать продукт и категорию? К добавленной «-категории» и «продукту» в конце? – haim770

+0

Нет, я сделаю кэш, чтобы посмотреть, соответствуют ли эти данные продукту или категории (мне не нужна логика для этого, просто нужно знать, куда его поместить). Конечный результат не будет иметь -product или -category. – webnoob

+0

Я не смогу сделать это с помощью регулярных выражений, мне нужно будет посмотреть в моей категории categoryService и посмотреть, соответствует ли строка текстуре древа или категории, и перенаправить соответственно. То же самое произойдет с 'productService', если категория вернется как null. – webnoob

ответ

2

Вы можете написать собственный маршрут, чтобы служить этой цели:

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

, а затем вы можете иметь соответствующий контроллер:

public class CategoryController: Controller 
{ 
    public ActionResult Index(string[] categories) 
    { 
     ... The categories action argument will contain a list of the provided categories 
      in the url 
    } 
} 
+0

Отлично, спасибо Дарин. Я скоро поеду с ним. – webnoob

+0

Еще раз спасибо, пользовательский маршрут именно то, что я искал. – webnoob

+0

Возможно, это повлияет на отправку формы? Я пытаюсь опубликовать представление, которое я использовал с помощью этого маршрута, и оно не отправляется на контроллер. – webnoob

Смежные вопросы