我在构建允许两种路由的ASP.NET MVC页面时遇到问题。
我有一个数据库,其中所有页面都存储了一个url-path,如: / Site1 / Site2 / Site3 我试图在我的第一条路线中使用 IRouteConstraint 来检查所请求的内容 site是我的数据库中的一个站点(永久链接)。
在第二种情况下,我想使用默认的asp.net mvc {controller} / {action} 功能,以便从* .cshtml提供简单的访问。
现在我不知道这是不是最好的方法。此外,我有问题,如何使用IRouteContraint。
有没有人对此有任何体验?
我正在使用asp.net mvc 5.
问题解决了,最终解决方案:
添加以下两条路线:
routes.MapRoute(
"FriendlyUrlRoute",
"{*FriendlyUrl}"
).RouteHandler = new FriendlyUrlRouteHandler();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Page", action = "Load", id = UrlParameter.Optional },
namespaces: controllerNamespaces.ToArray()
);
我自己的路由处理程序:
public class FriendlyUrlRouteHandler : System.Web.Mvc.MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext requestContext)
{
var friendlyUrl = (string)requestContext.RouteData.Values["FriendlyUrl"];
WebPageObject page = null;
if (!string.IsNullOrEmpty(friendlyUrl))
{
page = PageManager.Singleton.GetPage(friendlyUrl);
}
if (page == null)
{
page = PageManager.Singleton.GetStartPage();
}
// Request valid Controller and Action-Name
string controllerName = String.IsNullOrEmpty(page.ControllerName) ? "Page" : page.ControllerName;
string actionName = String.IsNullOrEmpty(page.ActionName) ? "Load" : page.ActionName;
requestContext.RouteData.Values["controller"] = controllerName;
requestContext.RouteData.Values["action"] = actionName;
requestContext.RouteData.Values["id"] = page;
return base.GetHttpHandler(requestContext);
}
}
答案 0 :(得分:2)
您可以使用 MVC 5 中的属性路由,并将属性路由与基于约定的路由相结合,以检查控制器类或操作方法所需的条件。
你可以自己制定约束,在这样的动作方法中使用它:
public class ValuesConstraint : IRouteConstraint
{
private readonly string[] validOptions;
public ValuesConstraint(string options)
{
validOptions = options.Split('|');
}
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
object value;
if (values.TryGetValue(parameterName, out value) && value != null)
{
return validOptions.Contains(value.ToString(), StringComparer.OrdinalIgnoreCase);
}
return false;
}
}
要使用属性路由,您只需在配置期间调用MapMvcAttributeRoutes
,然后调用常规约定路由。你也应该在映射属性之前添加约束,如下面的代码:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
var constraintsResolver = new DefaultInlineConstraintResolver();
constraintsResolver.ConstraintMap.Add("values", typeof(ValuesConstraint));
routes.MapMvcAttributeRoutes(constraintsResolver);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
现在,在您的控制器课程中,您可以检查路线并决定如何处理不同的网址,如下所示:
例如:// / mysite / Site1 和 / mysite / Site2 但不是 / mysite / Site3
[Route("mysite/{site:values(Site1|Site2)}")]
public ActionResult Show(string site)
{
return Content("from my database " + site);
}
你也可以在控制器类上进行各种检查。
我希望这能为你提供一些线索来实现你想要的东西。