MVC Alternative routing does not work with an additional parameter

I am trying to implement alternative routing in an MVC 5 web application.

I have a controller code:

namespace MyMvcProject.Web.Controllers { [RoutePrefix("account")] public class AccountController : Controller { [Route("{param}")] [Authorize] public ActionResult Index(string param = null) { ... 

which works great when hitting the URL: http://example.com/account/testparam . However, I would like to have param as an optional parameter.

I tried changing [Route("{param}")] to [Route("{param}*")] , but then the Index() method is never entered. I also tried changing it to [Route("{param:string=Test}")] , but I get a routing error with the term string .

My RoutConfig.cs contains:

  public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapMvcAttributeRoutes(); routes.MapRoute( name: "Default", url: "{controller}/{action}/{param}", defaults: new { controller = "Home", action = "Index", param = UrlParameter.Optional } ); } 

Does anyone know how I can get Index() have an optional parameter using this alternative routing syntax? This is very useful in other parts of my application, so I would like to save the RoutePrefix and Route decorators.

UPDATE

I'm still trying to figure this out, so I changed my route decorator to [Route("{param:int=0}")] and my constructor to public ActionResult Index(int id) , and it works as expected (i.e. http://example.com/account behaves as if http://example.com/account has been entered, which is exactly what I want using only string data types.

When I change the decorator to: [Route("{id:string=\"\"}")] and the constructor to public ActionResult Index(string id) , and I see a runtime error:

The built-in constraint converter like 'DefaultInlineConstraintResolver' could not resolve the following built-in constraint: 'string'.

+6
source share
2 answers

Found the answer here . Do I need to make param nullable using ? .

 [Route("{param?}")] [Authorize] public ActionResult Index(string param = null) { ... } 

Hope this helps someone in the future. There are not many links that I could find on this topic.

+6
source

@ Brett's answer is great: adding ? to a parameter in the Route attribute, and then providing a default value in the action signature allows this parameter to be optional.

And here's a great article from Mike Wason on Attribute Routing in Web API 2 , which includes a snippet on optional parameters.

Mike also talks about applying a few restrictions and says:

You can apply several restrictions to a parameter separated by a colon.

  [Route("users/{id:int:min(1)}")] public User GetUserById(int id) { ... } 

which also works great ... until you need a few restrictions and an optional parameter.

As you know, the application ? allows the parameter to be optional. Therefore, taking the above example, we can assume that

 [Route("users/{id:int?:min(1)}")] public User GetUserById(int id = 1) { ... } 

restricts the id parameter to an integer greater than 0 or empty (in this case, the default value of 1 is used). In fact, we get an error message:

The built-in constraint converter like 'DefaultInlineConstraintResolver' could not resolve the following built-in constraint: 'int?'.

It turns out that the order of restrictions makes sense! Just adding an optional constraint ? after all other restrictions give the expected behavior

 [Route("users/{id:min(1):int?}")] public User GetUserById(int id = 1) { ... } 

This works for more than two limitations, for example,

 [Route("users/{id:min(1):max(10):int?}")] public User GetUserById(int id = 1) { ... } 
+6
source

Source: https://habr.com/ru/post/976397/


All Articles