我们目前正在为我们的应用程序创建一个小型CMS模块,其中现有路由和控制器具有高优先级,而只有在默认路由中不存在提供的URL时,才会加载通过CMS动态创建的页面。
我已经看过这个:Dynamic Routes from database for ASP.NET MVC CMS 但它在路线之前优先考虑动态创建的页面。
这是我们的默认路线:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Store", action = "Index", id = UrlParameter.Optional }
);
除了默认路由之外,我们还有其他路由使用这样的前缀:
routes.MapRoute(
name: "Media",
url: "m/{*url}",
defaults: new { controller = "Content", action = "GetContent", contentlibrary = "Media" },
constraints: new { url = @"(.*?)\.(png|jpg|pdf|mpeg|mp3|mp4)" }
);
更新1: 我创建了一个IRouteConstraint来验证Controller是否存在默认路由。这是我的代码:
public class ControllerValidatorConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
var tempRequestContext = httpContext.Request.RequestContext;
IController controller = null;
try
{
controller = ControllerBuilder.Current.GetControllerFactory().CreateController(httpContext.Request.RequestContext, values["controller"].ToString());
}
catch (Exception ex)
{
}
return controller != null;
}
}
然后路由:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Store", action = "Index", id = UrlParameter.Optional },
constraints: new { url = new ControllerValidatorConstraint() }
);
routes.MapRoute(
name: "Page",
url: "{*url}",
defaults: new { controller = "Content", action = "GetPage" },
constraints: new { url = @"(.*?)(|.cshtml)" },
namespaces: new[] { "AppCore.Controllers" }
);
这已经像我想要的那样工作了。唯一剩下的问题是Match()方法。 Match()方法当前正在创建控制器的实例,我用Try-Catch块包装它,因为它抛出了与提供的路径相关的错误,该错误不作为临时解决方案存在,但这仍然是错误的。
我差不多了,我只需找到一种合适的方法来检查控制器是否存在。反思是一个糟糕的选择吗?有什么更轻松的检查方法吗?谢谢!