自定义URL路由Net MVC 4

本文关键字:MVC Net 路由 URL 自定义 | 更新日期: 2023-09-27 18:04:55

我怎么能像这个url (http://www.domain.com/friendly-content-title)在Asp。. Net MVC 4.

备注:该参数总是动态的。URL可能不同:"friendly-content-title"

我尝试自定义属性,但我没有在ActionResult中捕获这个(friendly-content-title)参数。

视图:

  • /指数
  • 家庭/视频

ActionResult:

    // GET: /Home/        
    public ActionResult Index()
    {
        return View(Latest);
    }
    // GET: /Home/Video        
    public ActionResult Video(string permalink)
    {
        var title = permalink;
        return View();
    }

RouteConfig:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute(
            name: "Home Page",
            url: "{controller}/{action}",
            defaults: new { controller = "Home", action = "Index" }
        );
        routes.MapRoute(
            name: "Video Page",
            url: "{Home}/{permalink}",
            defaults: new { controller = "Home", action = "Video", permalink = "" }
        );
    }

我该怎么做捕获url (/friendly-content-title)?

自定义URL路由Net MVC 4

要启用属性路由,请在配置时调用MapMvcAttributeRoutes。以下是代码片段:

     public class RouteConfig
        {
            public static void RegisterRoutes(RouteCollection routes)
             {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
                routes.MapMvcAttributeRoutes();
             }
        }

在MVC5中,我们可以结合属性路由和基于约定的路由。以下是代码片段:

        public static void RegisterRoutes(RouteCollection routes)
         {
          routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
          routes.MapMvcAttributeRoutes();
          routes.MapRoute(
          name: "Default",
          url: "{controller}/{action}/{id}",
          defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
       );
  }

通过在路由参数中添加问号,可以很容易地使URI参数成为可选的。我们也可以通过使用表单参数=value来指定一个默认值。

Radim Köhler的解决方案很好。

但是如果你想对路由进行更多的控制,另一个选择是使用自定义约束。

这里有一个例子

RouteConfig.cs

routes.MapRoute(
            "PermaLinkRoute", //name of route
            "{*customRoute}", //url - this pretty much catches everything
            new {controller = "Home", action = "PermaLink", customRoute = UrlParameter.Optional},
            new {customRoute = new PermaLinkRouteConstraint()});

那么在家用控制器上你可以设置这样的动作

HomeController.cs

public ActionResult PermaLink(string customRoute)
{
    //customRoute would be /friendly-content-title..do what you want with it
}

MapRoute调用中,我们将IRouteConstraint指定为第四个参数。

PermaLinkRouteConstraint.cs

public class PermaLinkRouteConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
        RouteDirection routeDirection)
    {
        var permaRoute = values[parameterName] as string;
        if (permaRoute == null)
            return false;
        if (permaRoute == "friendly-content-title")
            return true; //this indicates we should handle this route with our action specified
        return false; //false means nope, this isn't a route we should handle
    }
}

我只是想展示一个这样的解决方案,告诉你基本上可以做任何你想做的事情。

显然这需要调整。此外,你必须小心不要有数据库调用或Match方法内的任何缓慢,因为我们设置为通过你的网站来调用每一个请求(你可以移动它周围被称为在不同的顺序)。

如果Radim Köhler的解决方案适合你,我将使用它。

我们需要的是一些标记关键字。明确表示url应作为动态url处理,使用friendly-content-title。我建议使用关键字video,然后这将是路由的映射:

routes.MapRoute(
    name: "VideoPage",
    url: "video/{permalink}",
    defaults: new { controller = "Home", action = "Video", permalink = "" }
);
routes.MapRoute(
    name: "HomePage",
    url: "{controller}/{action}",
    defaults: new { controller = "Home", action = "Index" }
);
现在,因为VideoPage被声明为第一个,所以所有的url (如下所示)将被视为动态的:
// these will be processed by Video action of the Home controller
domain/video/friendly-content-title 
domain/video/friendly-content-title2 

而任何其他(controllerName/ActionName)将以标准方式处理