Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use constraints in ASP.net MVC 4 RouteConfig.cs?

I'm trying to get some routing constraints working using the latest asp.net mvc 4 architecture. Under App_Start there is a file called RouteConfig.cs.

If I remove the constraints section from my example below, the url works. But I need to add some constraints so that the url doesnt match on everything.

Should work: /videos/rating/1

Shold NOT work: /videos/2458/Text-Goes-Here

This is what I have:

//URL: /videos/rating/1
routes.MapRoute(
    name: "Videos",
    url: "videos/{Sort}/{Page}",
    defaults: new { controller = "VideoList", action = "Index", Sort = UrlParameter.Optional, Page = UrlParameter.Optional },
    constraints: new { Sort = @"[a-zA-Z]", Page = @"\d+"}
);
like image 909
Maddhacker24 Avatar asked Nov 30 '12 18:11

Maddhacker24


People also ask

What is RouteConfig Cs in MVC?

In MVC, routing is a process of mapping the browser request to the controller action and return response back. Each MVC application has default routing for the default HomeController. We can set custom routing for newly created controller. The RouteConfig. cs file is used to set routing for the application.

What is the difference between RouteConfig and WebApiConfig?

RouteConfig. cs is exclusively for configuring ASP.NET routes. WebApiConfig. cs is for any Web API related configuration, including Web-API-specific routes, Web API services, and other Web API settings.

Can we add constraints to the route in MVC?

Attribute Routing is introduced in MVC 5.0. We can also define parameter constraints by placing a constraint name after the parameter name separated by a colon. There are many builtin routing constraints available. We can also create custom routing constraints.

Which method is used to apply a route constraint in an ASP.NET MVC web application?

The RouteCollection class in ASP.NET Core MapRoute is an overloaded method that accepts constraints as a parameter. You can use this to pass your constraint to the route.


2 Answers

If you want multiple optional parameters on the same route, you will run into trouble because your urls must always specify the first one in order to use the second one. Just because you use constraints doesn't stop it from evaluating the parameters, it instead fails to match this route.

Take this for example: /videos/3

When this is trying to match, it finds videos, and says, "OK, I still match". Then it looks at the next parameter, which is Sort and it gets the value 3, then checks it against the constraint. The constraint fails, and so it says "OPPS, I don't match this route", and it moves on to the next route. In order to specify the page without the sort parameter defined, you should instead define 2 routes.

//URL: /videos/rating/1
routes.MapRoute(
    name: "Videos",
    url: "videos/{Sort}/{Page}",
    defaults: new { controller = "VideoList", action = "Index", Page = UrlParameter.Optional },
    constraints: new { Sort = @"[a-zA-Z]+", Page = @"\d+"}
);

//URL: /videos/1
routes.MapRoute(
    name: "Videos",
    url: "videos/{Page}",
    defaults: new { controller = "VideoList", action = "Index", Sort = "the actual default sort value", Page = UrlParameter.Optional },
    constraints: new { Page = @"\d+"}
);

I put the most specific routes first when possible and end with the least specific, but in this case the order should not matter because of the constraints. What I mean by specific is most defined values, so in this case you must define the sort in the first route, and you also can specify the page, so it is more specific than the route with just the page parameter.

like image 53
Nick Larsen Avatar answered Nov 09 '22 10:11

Nick Larsen


My input maybe rather late, but for others still searching for answers.To keep things simple, i would use the following in my RoutesConfig file

 routes.MapRoute(
     name: "Videos",
     url: "{controller}/{action}/{id}",
     defaults: new { controller = "VideoList", action = "Index", id="" },
     constraints: new { id = @"\d+"}
     );

Depending on your choice of implementation, id could be UriParameter.Optional, but in this scenario it is going to be id="" ,because we will be passing a string/int during runtime.

This style was adopted from http://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/creating-a-route-constraint-cs

One thing to keep in mind by convention controller classes always end with controller e.g VideoListController class. This class should be listed under the controller folder containing the following method

public ActionResult Index(string id)
{
    // note this maps to the action
    // random implementation
    ViewBag.Message=id;
    View()
}

// note this approach still matches any string... To match only integers, the Index method has to be rewritten

public ActionResult Index(int id)
{
     // note this maps to the action
     ViewBag.Message=id;
     View()
}

Consequently, this approach works for VideoList/Index/12 but upon putting VideoList/Index/somerandomtext it throws an error during runtime. This could be solved by employing error pages. I hope this helps. Vote if its quite useful.

like image 23
Tolani Avatar answered Nov 09 '22 11:11

Tolani