我需要能够拥有类似以下网址的路线。
/authorid
/documentid
/authorid/documentid
我想不要做
/author/1
/document/5
author/1/document/25
如何做到这一点?
澄清。 文档和作者可以具有相同的ID。但作者应该优先考虑。
作者:{ID:“djQuery”}
文件:{Aurhor:“Bob”,ID:“djQuery”}
应该可以通过/ Bob / djQuery
访问但是如果你只是去/ djQuery,你应该得到一个djQuery文档列表。
答案 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。
如果有,那里就会发生冲突。