Custom URL Routing in Asp.Net MVC 4

2019-04-12 23:34发布

How can i do like this url (http://www.domain.com/friendly-content-title) in Asp.Net MVC 4.

Note: This parameter is always dynamic. URL may be different: "friendly-content-title"

I try to Custom Attribute but I dont catch this (friendly-content-title) parameters in ActionResult.

Views:

  • Home/Index
  • Home/Video

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

    }

What should I do for catch to url (/friendly-content-title)?

3条回答
Summer. ? 凉城
2楼-- · 2019-04-13 00:18

Radim Köhler's solution is a good one.

But another option if you want more control over routing is using a custom constraint.

Here's an example

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

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.

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).

I would go with Radim Köhler's solution if it works for you.

查看更多
▲ chillily
3楼-- · 2019-04-13 00:20

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. I would suggest to use the keyword video, and then this would be the mapping of routes:

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:

// 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

查看更多
迷人小祖宗
4楼-- · 2019-04-13 00:23

To enable attribute routing, call MapMvcAttributeRoutes during configuration. 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. 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. We can also specify a default value by using the form parameter=value. here is the full article.

查看更多
登录 后发表回答