如何拥有前往2个目的地的路线

时间:2011-09-06 16:09:51

标签: asp.net asp.net-mvc routes

我需要能够拥有类似以下网址的路线。

/authorid
/documentid
/authorid/documentid

我想不要做

/author/1   
/document/5
author/1/document/25

如何做到这一点?

澄清。 文档和作者可以具有相同的ID。但作者应该优先考虑。

作者:{ID:“djQuery”}

文件:{Aurhor:“Bob”,ID:“djQuery”}

应该可以通过/ Bob / djQuery

访问

但是如果你只是去/ djQuery,你应该得到一个djQuery文档列表。

5 个答案:

答案 0 :(得分:4)

您可以通过三条路线和相应的RouteConstraints来实现您想要的目标。

首先,您需要建立您的路线:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Author_Document", // Route name
        "{author}/{document}", // URL
        new { controller = "ShowDocument", action = "AuthorDocument" }, // Parameters
        new { author = new MustBeValidAuthor(), document = new MustBeValidDocument() }

    routes.MapRoute(
        "Author", // Route name
        "{author}", // URL
        new { controller = "ShowDocument", action = "Author" }, // Parameters
        new { author = new MustBeValidAuthor() }

    routes.MapRoute(
        "Document", // Route name
        "{document}", // URL
        new { controller = "ShowDocument", action = "Document" }, // Parameters
        new { document = new MustBeValidDocument() }

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );
}

接下来,您需要创建RouteConstraints,它必须验证提供的信息是否有效:

using System; 
using System.Web; 
using System.Web.Routing;  

namespace ExampleApp.Extensions 
{ 
    public class MustBeValidAuthor : IRouteConstraint  
    { 
        public MustBeValidAuthor() { }

        private DbContext _db = new DbContext();

        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)    
        {      
            return (_db.Authors.Where(u => u.AuthorName == values[parameterName].ToString()).Count() > 0);
        }  
    } 

    public class MustBeValidDocument : IRouteConstraint  
    { 
        public MustBeValidDocument() { }

        private DbContext _db = new DbContext();

        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)    
        {      
            return (_db.Documents.Where(u => u.DocumentName == values[parameterName].ToString()).Count() > 0);
        }  
    } 
}

RouteConstraints将确认请求的有效性,并按此顺序放置路由符合您的要求。

答案 1 :(得分:2)

我不认为只通过配置路由就可以做到这一点。

问题是程序如何知道您发送的号码是作者还是文件。

你可以做的是/ 1进入一个页面,在那个页面上你检查它是一个文档还是一个作者,然后你做一个Response.Redirect到实际的页面,比如/ author / 1。

答案 2 :(得分:2)

假设你想要

/1  
/2  
/1/2

我认为你不能实现前两个网址会调用相同的路由规则。 您无法知道何时调用方法而不是其他方法。 我能想到的唯一解决方案是,如果你能辨别出id(例如1到10的id是authorid而其他的是documentId),你可以编写自定义规则处理程序并调用accordinlgy调用正确的方法。

否则你必须在网址中添加一些内容才能使其独一无二: “/ a1”表示authorid,“/ d2”表示DoumentId会有类似的东西

routes.MapRoute("", "a{authorId}", new { controller = "Home", action = "AuthorDetail" }, new { authorId = @"\d+" });
routes.MapRoute("", "d{documentId}", new { controller = "Home", action = "DocumentDetail" }, new { documentId = @"\d+" });

编辑:在您澄清后,来自counsellorben的答案应该做您想做的事

答案 3 :(得分:0)

您可以使用IsAuthorConstraint查找的内容来确定文档或作者。或者,在传递给文档或作者操作之前,您可以路由到桥接操作并将逻辑放在那里。

 context.MapRoute(
     "authorid",
     "{authorid}",
     new { action = "Author", controller = "Controller", 
                authorid = -1 },
     new { authorid = new IsAuthorConstraint() }
 );

 context.MapRoute(
     "document",
     "{documentid}",
     new { action = "Document", controller = "Controller", 
                documentid = -1 }
 );

 // assume overload on author action
 context.MapRoute(
     "document and author",
     "{authorid}/{documentid}",
     new { action = "Author", controller = "Controller", 
                documentid = -1, authorid = -1 }
 );

我不是在电脑上,所以可能不完全正确,但希望你明白这一点。

答案 4 :(得分:0)

你只能通过@counsellorben建议的路径约束来实现这一点,但是对于authorid和documentid,应该没有相同的id。

如果有,那里就会发生冲突。