简体   繁体   English

Asp.Net MVC 4中的自定义URL路由

[英]Custom URL Routing in Asp.Net MVC 4

How can i do like this url ( http://www.domain.com/friendly-content-title ) in Asp.Net MVC 4. 我如何在Asp.Net MVC 4中使用此URL( http://www.domain.com/friendly-content-title )。

Note: This parameter is always dynamic. 注意:此参数始终是动态的。 URL may be different: "friendly-content-title" 网址可能有所不同:“friendly-content-title”

I try to Custom Attribute but I dont catch this (friendly-content-title) parameters in ActionResult. 我尝试自定义属性,但我没有在ActionResult中捕获这个(友好内容标题)参数。

Views: 浏览次数:

  • Home/Index 首页/索引
  • Home/Video 首页/视频

ActionResult: 的ActionResult:

    // GET: /Home/        
    public ActionResult Index()
    {
        return View(Latest);
    }

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

RouteConfig: 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 = "" }
        );

    }

What should I do for catch to url (/friendly-content-title)? 我应该怎样做才能捕获到url(/ friendly-content-title)?

To enable attribute routing, call MapMvcAttributeRoutes during configuration. 要启用属性路由,请在配置期间调用MapMvcAttributeRoutes。 Following are the code snipped. 以下是代码剪切。

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

In MVC5, we can combine attribute routing with convention-based routing. 在MVC5中,我们可以将属性路由与基于约定的路由相结合。 Following are the code snipped. 以下是代码剪切。

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

It is very easy to make a URI parameter optional by adding a question mark to the route parameter. 通过向路由参数添加问号,可以非常轻松地将URI参数设置为可选。 We can also specify a default value by using the form parameter=value. 我们还可以使用form parameter = value指定默认值。 here is the full article. 是完整的文章。

Radim Köhler's solution is a good one. RadimKöhler的解决方案非常好。

But another option if you want more control over routing is using a custom constraint. 但是,如果您想要更多地控制路由,另一个选择是使用自定义约束。

Here's an example 这是一个例子

RouteConfig.cs 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()});

So then on your home controller you could have action like this 那么在你的家庭控制器上,你可以采取这样的行动

HomeController.cs HomeController.cs

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

The magic of this happens in the IRouteConstraint that we specified as the 4th argument in the MapRoute call. 这种情况发生在我们指定为MapRoute调用中第4个参数的IRouteConstraint中。

PermaLinkRouteConstraint.cs 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
    }
}

I just wanted to show a solution like this to show you can basically do anything you want. 我只想展示一个这样的解决方案,以表明你基本上可以做任何你想做的事情。

Obviously this would need to be tweaked. 显然这需要调整。 Also you'd have to be careful not to have database calls or anything slow inside the Match method, as we set that to be called for every single request that comes through to your website (you could move it around to be called in different orders). 此外,您必须注意不要在Match方法中进行数据库调用或任何缓慢的操作,因为我们设置为每个发送到您网站的请求调用(您可以移动它以便以不同的顺序调用) )。

I would go with Radim Köhler's solution if it works for you. 如果适合你,我会选择RadimKöhler的解决方案。

What we would need, is some marker keyword. 我们需要的是一些标记关键字。 To clearly say that the url should be treated as the dynamic one, with friendly-content-title . 要清楚地说,网址应该被视为动态网址,具有friendly-content-title I would suggest to use the keyword video , and then this would be the mapping of routes: 我建议使用关键字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" }
);

Now, because VideoPage is declared as the first, all the urls (like these below) will be treated as the dynamic: 现在,因为VideoPage被声明为第一个,所有的url (如下所示)将被视为动态:

// these will be processed by Video action of the Home controller
domain/video/friendly-content-title 
domain/video/friendly-content-title2 

while any other ( controllerName/ActionName ) will be processed standard way 而任何其他( controllerName/ActionName )将以标准方式处理

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM