Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Routing Via Method Attributes [closed]

In the StackOverflow Podcast #54, Jeff mentions they register their URL routes in the StackOverflow codebase via an attribute above the method that handles the route. Sounds like a good concept (with the caveat that Phil Haack brought up regarding route priorities).

Could someone provide some sample to make this happen?

Also, any "best practices" for using this style of routing?

like image 568
TorgoGuy Avatar asked May 21 '09 19:05

TorgoGuy


People also ask

Can you enable attribute routing in MVC?

To enable Attribute Routing, we need to call the MapMvcAttributeRoutes method of the route collection class during configuration. We can also add a customized route within the same method. In this way we can combine Attribute Routing and convention-based routing. A route attribute is defined on top of an action method.

What is the difference between routing and attribute routing in MVC?

ASP.NET MVC also supports new type of routing that is called Attribute Routing. In this, attribute participate to route url to particular action. Note: Attribute Routing is configuring before the Convention Routing or simple Routing. We can use Convention based Routing and Attribute Routing in the same project.

Why do we need attribute routing in MVC?

ASP.NET MVC5 and WEB API 2 supports a new type of routing, called attribute routing. In this routing, attributes are used to define routes. Attribute routing provides you more control over the URIs by defining routes directly on actions and controllers in your ASP.NET MVC application and WEB API.


2 Answers

UPDATE: This has been posted on codeplex. The complete source code as well as the pre-compiled assembly are there for download. I haven't had time to post the documentation on the site yet, so this SO post will have to suffice for now.

UPDATE: I added some new attributes to handle 1) route ordering, 2) route parameter constraints, and 3) route parameter default values. The text below reflects this update.

I've actually done something like this for my MVC projects (I have no idea how Jeff is doing it with stackoverflow). I defined a set of custom attributes: UrlRoute, UrlRouteParameterConstraint, UrlRouteParameterDefault. They can be attached to MVC controller action methods to cause routes, constraints, and defaults to be bound to them automatically.

Example usage:

(Note this example is somewhat contrived but it demonstrates the feature)

public class UsersController : Controller {     // Simple path.     // Note you can have multiple UrlRoute attributes affixed to same method.     [UrlRoute(Path = "users")]     public ActionResult Index()     {         return View();     }      // Path with parameter plus constraint on parameter.     // You can have multiple constraints.     [UrlRoute(Path = "users/{userId}")]     [UrlRouteParameterConstraint(Name = "userId", Regex = @"\d+")]     public ActionResult UserProfile(int userId)     {         // ...code omitted          return View();     }      // Path with Order specified, to ensure it is added before the previous     // route.  Without this, the "users/admin" URL may match the previous     // route before this route is even evaluated.     [UrlRoute(Path = "users/admin", Order = -10)]     public ActionResult AdminProfile()     {         // ...code omitted          return View();     }      // Path with multiple parameters and default value for the last     // parameter if its not specified.     [UrlRoute(Path = "users/{userId}/posts/{dateRange}")]     [UrlRouteParameterConstraint(Name = "userId", Regex = @"\d+")]     [UrlRouteParameterDefault(Name = "dateRange", Value = "all")]     public ActionResult UserPostsByTag(int userId, string dateRange)     {         // ...code omitted          return View();     } 

Definition of UrlRouteAttribute:

/// <summary> /// Assigns a URL route to an MVC Controller class method. /// </summary> [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class UrlRouteAttribute : Attribute {     /// <summary>     /// Optional name of the route.  If not specified, the route name will     /// be set to [controller name].[action name].     /// </summary>     public string Name { get; set; }      /// <summary>     /// Path of the URL route.  This is relative to the root of the web site.     /// Do not append a "/" prefix.  Specify empty string for the root page.     /// </summary>     public string Path { get; set; }      /// <summary>     /// Optional order in which to add the route (default is 0).  Routes     /// with lower order values will be added before those with higher.     /// Routes that have the same order value will be added in undefined     /// order with respect to each other.     /// </summary>     public int Order { get; set; } } 

Definition of UrlRouteParameterConstraintAttribute:

/// <summary> /// Assigns a constraint to a route parameter in a UrlRouteAttribute. /// </summary> [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class UrlRouteParameterConstraintAttribute : Attribute {     /// <summary>     /// Name of the route parameter on which to apply the constraint.     /// </summary>     public string Name { get; set; }      /// <summary>     /// Regular expression constraint to test on the route parameter value     /// in the URL.     /// </summary>     public string Regex { get; set; } } 

Definition of UrlRouteParameterDefaultAttribute:

/// <summary> /// Assigns a default value to a route parameter in a UrlRouteAttribute /// if not specified in the URL. /// </summary> [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class UrlRouteParameterDefaultAttribute : Attribute {     /// <summary>     /// Name of the route parameter for which to supply the default value.     /// </summary>     public string Name { get; set; }      /// <summary>     /// Default value to set on the route parameter if not specified in the URL.     /// </summary>     public object Value { get; set; } } 

Changes to Global.asax.cs:

Replace calls to MapRoute, with a single call to the RouteUtility.RegisterUrlRoutesFromAttributes function:

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

Definition of RouteUtility.RegisterUrlRoutesFromAttributes:

The full source is up on codeplex. Please go to the site if you have any feedback or bug reports.

like image 78
DSO Avatar answered Oct 13 '22 16:10

DSO


You can also try AttributeRouting, which is available from github or via nuget.

This is a shameless plug, as I am the project author. But dang if I'm not very happy using it. You might be too. There is plenty of documentation and sample code in the github repository wiki.

With this library, you can do a lot:

  • Decorate your actions with GET, POST, PUT, and DELETE attributes.
  • Map multiple routes to a single action, ordering them with an Order property.
  • Specify route defaults and constraints using attributes.
  • Specify optional params with a simple ? token before the parameter name.
  • Specify the route name for supporting named routes.
  • Define MVC areas on a controller or base controller.
  • Group or nest your routes together using route prefixes applied to a controller or base controller.
  • Support legacy urls.
  • Set the precedence of routes among the routes defined for an action, within a controller, and among controllers and base controllers.
  • Generate lowercase outbound urls automatically.
  • Define your own custom route conventions and apply them on a controller to generate the routes for actions within the controller without boilerplate attributes (think RESTful style).
  • Debug your routes using a supplied HttpHandler.

I'm sure there's some other stuff I'm forgetting. Check it out. It's painless to install via nuget.

NOTE: As of 4/16/12, AttributeRouting also supports the new Web API infrastructure. Just in case you're looking for something that can handle that. Thanks subkamran!

like image 45
spot Avatar answered Oct 13 '22 16:10

spot