0

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

revolver
  • 95
  • 1
  • 8

1 Answers1

1

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();
}
Anish Patel
  • 4,332
  • 1
  • 30
  • 45
  • Thanks for your response but actually i dont want to use any prefix in the route. I just want to display them like domain/categoryName and domain/surveyName. Is this possible? – revolver Jul 29 '15 at 13:28
  • This isn't possible because there is no way to tell the difference between _domain/categoryName_ and _domain/surveyName_ when `categoryName` and `surveyName` are both strings. – Anish Patel Jul 29 '15 at 13:43
  • But they are different controllers? and so actions. You mean there is no logic when asp .net routes these urls to to the related controller and action methods? – revolver Jul 29 '15 at 14:34
  • Of course there is logic in _ASP.NET_ to map urls to routes. However, you have defined two routes whose patterns clash. `{categoryName}` and `{surveyName}` is the same as `{anything}` and `{anything}`, how are you supposed to differentiate intelligently? Your route pattern means match **any** string, it doesn't matter what you call the variable it is to be assigned to. – Anish Patel Jul 29 '15 at 14:53
  • Then i have to put a convention before of the route parameter. Thanks for your responses – revolver Jul 29 '15 at 16:34