ASP.NET MVC页面URL和控制器/动作路由

时间:2014-06-23 19:57:47

标签: c# asp.net asp.net-mvc asp.net-mvc-routing

我在构建允许两种路由的ASP.NET MVC页面时遇到问题。

我有一个数据库,其中所有页面都存储了一个url-path,如: / Site1 / Site2 / Site3 我试图在我的第一条路线中使用 IRouteConstraint 来检查所请求的内容 site是我的数据库中的一个站点(永久链接)。

在第二种情况下,我想使用默认的asp.net mvc {controller} / {action} 功能,以便从* .cshtml提供简单的访问。

现在我不知道这是不是最好的方法。此外,我有问题,如何使用IRouteContraint。

有没有人对此有任何体验?

我正在使用asp.net mvc 5.

问题解决了,最终解决方案:

  1. 添加以下两条路线:

    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()
    );
    
  2. 我自己的路由处理程序:

    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);
        }
    }
    

1 个答案:

答案 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);
}

你也可以在控制器类上进行各种检查。

我希望这能为你提供一些线索来实现你想要的东西。