Fka
Fka

Reputation: 6234

ASP.NET MVC4 Custom routing

I want to create simple blog engine. For fancy and clean url I'd like to use routing mechanism implemented in MVC4.

I added to RouteConfig.cs this lines:

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

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

        routes.MapRoute(
            name: "ArticleList",
            url: "Articles/{category}/{page}",
            defaults: new
                          {
                              controller = "Articles",
                              category = UrlParameter.Optional,
                              page = 1
                          });
    }
}

And if I write in web browser url:

http://localhost:6666/Articles/SomeCategory/3

I want to move to this controller:

public class ArticlesController : ControllerBase<IHomeService>
{
    public ActionResult Index(string category, int page = 0)
    {
        return View("~/Views/Article/Articles.cshtml");
    }

}

with parameters category = "SomeCategory" and page = 1.

All I recieve is Server Error in '/' Application. The resource cannot be found.

What is wrong?

Upvotes: 5

Views: 12699

Answers (3)

Anil Sharma
Anil Sharma

Reputation: 615

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.

Upvotes: -1

Siyamand
Siyamand

Reputation: 54

The problem is, you have an optional parameter in the middle of your {controller}/{category}/{page} path. ASP.NET routing has problem with that, because if category is not provided, it has no way to detect that the category is not provided.

Upvotes: 0

Raciel R.
Raciel R.

Reputation: 2156

       routes.MapRoute(
            name: "ArticleList",
            url: "{controller}/{category}/{page}",
            defaults: new
            {
                category = UrlParameter.Optional,
                page = 1,
                action = "Index"
            },
            constraints: new
            {
                controller = "Articles"
            }
       );


        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

EDIT

I should have added this to the answer but I was in a hurry:

  1. Register your custom routes first, the more custom the more priority they have.
  2. In the example above using the constraints or hard-coding the route produces the same result. Constraints are more flexible because you can use regex to restrict the controllers/actions/parameters values that your route is for. For instance, if you add a new route that uses the /category/page pattern your can then modify the controller constraint accordingly:

    constraints: new { controller = @"^(Articles|AnotherController)$" }

Upvotes: 5

Related Questions