C# ASP.NET MVC页面URL和控制器/操作路由
我在构建允许两种路由的ASP.NET MVC页面时遇到问题 我有一个数据库,其中所有页面都以url路径存储,如:/Site1/Site2/Site3 我尝试在第一条路线中使用IRouteConstraint,检查请求的路线是否正确 站点是我的数据库中的站点(permalink) 在第二种情况下,我想使用默认的asp.net mvc{controller}/{action}功能,从*.cshtml提供简单的访问 现在我不知道这是不是最好的方法。此外,我还有一个问题,如何使用IRouteContracint根 有人对此有经验吗 我正在使用asp.NETMVC5 问题已解决,最终解决方案:C# ASP.NET MVC页面URL和控制器/操作路由,c#,asp.net,asp.net-mvc,asp.net-mvc-routing,C#,Asp.net,Asp.net Mvc,Asp.net Mvc Routing,我在构建允许两种路由的ASP.NET MVC页面时遇到问题 我有一个数据库,其中所有页面都以url路径存储,如:/Site1/Site2/Site3 我尝试在第一条路线中使用IRouteConstraint,检查请求的路线是否正确 站点是我的数据库中的站点(permalink) 在第二种情况下,我想使用默认的asp.net mvc{controller}/{action}功能,从*.cshtml提供简单的访问 现在我不知道这是不是最好的方法。此外,我还有一个问题,如何使用IRouteContra
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);
}
}
您可以使用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 }
);
}
现在,在控制器类上,您可以检查路由并决定如何处理不同的URL,如下所示:
例如:///mysite/Site1和/mysite/Site2但不是/mysite/Site3
[Route("mysite/{site:values(Site1|Site2)}")]
public ActionResult Show(string site)
{
return Content("from my database " + site);
}
您还可以在控制器类上执行各种检查
我希望这能给你一点线索来实现你想要的东西。谢谢,但是当我使用属性路由时,我如何处理动态路由,哪些存储在我的数据库中?您可以从数据库中获取ValuesConstraint类中的rout值,并编写适合您需要的约定,然后将其应用于控制器类中的操作方法。我找到了解决我的问题的完美解决方案: