我需要使用以下网址实现MVC网站:
其中匹配条件是url以“wiki”结尾。
不幸的是,下面的catch-all仅在url的最后部分有效:
routes.MapRoute("page1", // Route name
"{*path}/wiki", // URL with parameters
new { controller = "Wiki", action = "page", version = "" } // Parameter defaults
我没有时间浏览MVC扩展性选项,所以我想知道实现它的可能选择是什么?任何样本/示例都会非常棒!
答案 0 :(得分:15)
正如您所提到的,catch-all参数只能出现在路径的末尾 - 您发布的代码会抛出运行时错误,如果您尝试运行,则会给出黄色的死亡屏幕应用
构建自定义路由方案有几个可扩展点。这些是 - Route,RouteBase和IRouteHandler。
您可以通过扩展RouteBase来创建要处理的路由的生成列表。通常,您将遵循具有接收资源(控制器名称)的构造函数的模式,然后为其分配它负责的路由列表,然后将其映射到global.asax中。以下是您可以构建的一些示例代码:
public class MyRoute : RouteBase
{
private List<Route> _routes = new List<Route>();
public MyRoute(string resource)
{
// make a Resource property, not shown in this example
this.Resource = resource;
// Generate all your routes here
_routes.Add(
new Route("some/url/{param1}",
new McvRouteHandler {
Defaults = new RouteValueDictionary(new {
controller = resource,
action = actionName
}),
Constraints = new RouteValueDictionary()
);
_routes.Add(...); // another new route
}
public override RouteData GetRouteData(HttpContextBase context)
{
foreach (var route in _routes)
{
var data = route.GetRouteData(context);
if (data != null)
{
return data;
}
}
return null;
}
public override VirtualPathData GetVirtualPath(RequestContext context, RouteValueDictionary rvd)
{
foreach (var route in _routes)
{
var path = route.GetVirtualPath(context, rvd);
if (path != null)
{
return path;
}
}
return null;
}
}
要使用路由类,请在Global.asax中执行routes.Add(new MyRoute("page1"));
。
如果你需要更多控制,你可以实现一个IRouteHandler,而不是为你的路由创建MvcRouteHandlers(),如上例所示,使用你自己的IRouteHandler。这将允许您覆盖从请求数据中选择控制器的逻辑。
整个框架非常易于扩展,但为了正确完成,您需要学习很多东西。我建议如果可能的话,只需重新安排你的URL就可以利用catch-all参数。