2014-02-12 143 views
0

我需要一些自定义路由为我的网站。 我需要的URL出现这样ASP.NET MVC - 自定义路由

  • www.domain.com/categoryname/subcategoryname
  • www.domain.com/categoryname
  • www.domain.com/categoryname/productname
  • www.domain.com/categoryname/subcategoryname/productname

请注意两个大胆的网址AR e仅在URL的最后部分有所不同 我无法将控制器名称和操作名称用于此类型的URL。 如何在ASP.NET MVC中使用路由表执行此操作? 我这是不可能与路由表,是否有另一个工具来做到这一点?

感谢

回答

1

我知道几种方法。

首先,我假设两个URL之间有某种区别。如果“苹果”也是一个有效的产品和类别名称,那么当然,如果URL模式相同,则无法区分它们。并且始终确保您的路由按正确的顺序定义,路由引擎会将请求路由到第一个匹配路由,因此请首先放置更具体的路由。

最简单的是,如果在subcategorynameproductname之间存在语法上的差异。然后路线限制是要走的路。您可以为这两个参数定义不同的正则表达式,并且它们将完美工作,路由引擎会知道将哪个请求路由到哪里。 (见herehere

如果不存在语法差别,您能介绍一个。例如:

www.domain.com/categoryname/s_subcategoryname 
www.domain.com/categoryname/p_productname 

它不是太难看,也没有冲突。

然后,你也可以实现你自己的IRouteConstraint。这样你可以定义任何你想区分这两条路线的逻辑。在列表中收集可能产品的名称,然后将其与产品路线进行匹配。 (见here。)

您也可以定义自定义路由处理程序或HTTP处理程序,它执行相同的逻辑,前一段和做了Server.Transfer()实际执行不同的操作,但它的很多混乱,所以我不会”没有建议。

0

没有,这是不可能这样的,因为没有URL路由引擎会知道如何将此类URL匹配到相应的路由。您需要以某种方式区分这些类型的网址,因此很清楚要使用哪一种类型的网址。

好的,好吧,有可能是一种方式,但它有点hacky ...你只是路由到一些通用的行动,那里你会比较最后一部分到你的记录,并决定,如果参数是一个产品名称或一个子类别名称,并返回一个视图基于...

1

实现此目的的一种方法是通过继承IRouteConstraint创建自定义RouteConstraint并将您的url保存在xml中。你需要知道的页面模板类型,所以你可以在这样一个枚举存储这样的信息:

public enum TemplateType 
{ 
    Home, 
    Product, 
    Category 
} 

下面是一个示例XML,你可以用它来存储数据:

<Sitemap> 
    <Item url="/home" TemplateType="Home" /> 
    <Item url="/products/category" TemplateType="Category"> 
    <Item url="/products/category/product" TemplateType="Product" /> 
    </Item> 
</Sitemap> 

后您将需要方法来提取Sitemap节点并获取特定节点。您只需要反序列化xml并遍历它即可找到特定的url。

您的自定义RouteConstraing应该是这样的:

public class CustomRouteConstraint : IRouteConstraint 
{ 
    #region IRouteConstraint Members 

    private TemplateType m_type; 

    public CustomRouteConstraint(TemplateType type) 
     :base() 
    { 
     m_type = type; 
    } 


    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     bool returnValue = false; 
     SitemapNode sitemapNode = GetSiteMapNode(httpContext.Request); 

     if (sitemapNode != null && sitemapNode.TemplateType == m_type) 
     { 
      return true; 
     } 

     return returnValue; 

    } 

    #endregion 

    private static SitemapNode GetSiteMapNode(HttpRequestBase request) 
    { 
     //get the aboslute url 
     string url = request.Url.AbsolutePath; 

     return SitemapManager.GetSiteMapNode(url); 
    } 
} 

后你在的RegisterRoutes方法的Global.asax文件都的这地方,你需要做这样的事情:

routes.MapRoute(
    "", // Route name 
    route, // URL with parameters 
    new { lang = "en", region = "us", controller = "Category", action = "Index" }, 
    new { param1 = new CustomRouteConstraint(TemplateType.Category) }); 

希望这会有所帮助。