Search code examples
asp.net-mvccontrolleractionattributerouting

Same route parameters with different controllers' action methods causes an error in Asp .Net MVC


I m using attribute routing feature of Asp .Net Mvc. My first action is like below which is placed in SurveyController

    [Route("{surveyName}")]
    public ActionResult SurveyIndex()
    {
        return View();
    }

And my second action is like below which is placed in MainCategoryController

    [Route("{categoryUrlKey}")]
    public ActionResult Index(string categoryUrlKey)
    {
        return View();
    }

I'm not using convention based routing. Below is my 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.MapAttributeRoutes();
    }

Now the problem is when i click to a survey it redirects to the MainCategory/Index route. I know it is because of same route pattern but i cant change this into another thing. how can I handle this situation? Thanks


Solution

  • You should prefix the routes on your MainCaregoryController, either at the controller level like this:

    [RoutePrefix("category")]
    public class MainCategoryController : Controller {
    

    or at the action level like this:

    [Route("category/{categoryUrlKey}")]
    public ActionResult Index(string categoryUrlKey)
    {
        return View();
    }
    

    Routes should not clash. This route:

    [Route("{categoryUrlKey}")]
    public ActionResult Index(string categoryUrlKey)
    {
        return View();
    }
    

    matches any string and passes that string value into the action, so without a prefix it will match:

    http://localhost/validcategorykey
    

    and

    http://localhost/something/id/isthispointmakingsense
    

    and your categoryUrlKey parameter would equal "validcategorykey" in the first instance and "something/id/isthispointmakingsense" in the second.

    Now as for this route:

    [Route("{surveyName}")]
    public ActionResult SurveyIndex()
    {
        return View();
    }
    

    This just won't work period. This needs to be changed to:

    [Route("survey/{surveyName}")]
    public ActionResult SurveyIndex(string surveyName)
    {
        return View();
    }