简体   繁体   中英

MVC Conventional and Attribute routing not working together

I am using conventional routing on an ASP.Net MVC project and would like to enable Attribute routing in parallel. I have created the following but I am getting a 404 on the conventional route when enabling attribute routing

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 }
    );
}

Controller

[RoutePrefix("Registration")]
public class RegistrationController : Controller
{    
    [HttpGet]
    [Route("Add/{eventId}")]
    public ActionResult Add(int eventId)
    {
    }
}

Calling

http://localhost/Registration/Add/1

Works, while calling

http://localhost/Registration/Add?eventId=1

No longer works and responds with 404 NotFound

Should work if you make the {eventId} template parameter optional in the route template

[RoutePrefix("Registration")]
public class RegistrationController : Controller {
    //GET Registration/Add/1
    //GET Registration/Add?eventId=1
    [HttpGet]
    [Route("Add/{eventId:int?}")]
    public ActionResult Add(int eventId) {
        //...
    }
}

The reason the two were not working is that the route template Add/{eventId} means that the route will only match if the {eventId} is present, which is why

http://localhost/Registration/Add/1

works.

By making it ( eventId ) optional eventid? it will allow

http://localhost/Registration/Add

to work as the template parameter is not required. This will now allow query string ?eventId=1 to be used, which the routing table will use to match the int eventId parameter argument on the action.

http://localhost/Registration/Add?eventId=1

I also got this issue. Which MVC version are you using? I faced this issue with MVC in asp.net core. I think this is a flaw as if you provide Routing attribute on any action method, its conventional route is over ridden and is not longer available so you get 404 error. For this to work, you can provide another Route attribute to your action method like this. This will work

 [Route("Add/{eventId}")]  
 [Route("Add")]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM