2

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 Answers 3

6

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.

Sign up to request clarification or add additional context in comments.

Comments

4

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.

2 Comments

The constraint here could be a bit more difficult, namely if the friendly titles could differ a lot. The keyword (e.g. video) would most likely simplify stuff. But I do like that you came up with that. Because really, with IRouteConstraint we can do a lot of magic. And maybe, even in this case, it could be suitable. You've got my vote ;)
@mstfcck I don't understand your comment. This would let you handle the friendly titles anyway you want to. Can you be more specific in what you're looking for if neither of the two posted solutions work for you?
3

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

2 Comments

I try it. But I dont want that.
I guess I do understand ... you do not like the video/ part. But I would say, that this will be the most suitable way - I would say. Why? because without this keyword, the routing mechanism will never be sure if the url domain/home is the controller or the name of video (Home). Lastly, I would say, that the keyword (some reasonable ;) could even help your users to understand what is behind the domain/video/...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.