asp.net-mvcasp.net-mvc-4asp.net-mvc-routingmvcroutehandler

.net mvc route default controller/action but not default parameters


I created this route

          routes.MapRoute( 
                name: "Survey", 
                url: "{controller}/{action}/{surveyid}/{userid}/{hash}", 
                defaults: new { controller = "Home", action = "Survey" }, 
                constraints: new { surveyid = @"\d+", userid = @"\d+" } 
           );

When I then browse to

http://localhost:3086/Home/Survey/1/1/3r2ytg

It works, however if I browse to

http://localhost:3086/1/1/3r2ytg

it does not work.

If I then changed the route like so

        routes.MapRoute(
            name: "Survey",
            url: "{surveyid}/{userid}/{hash}",
            defaults: new { controller = "Home", action = "Survey" },
            constraints: new { surveyid = @"\d+", userid = @"\d+" }
        );

The exact opposite would work (and that makes sense).

But I am curious with the first route i thought both URLs should work since it shoudl grab the default controller and action when none is given.

Update

In the end I went with only this

        routes.MapRoute(
            name: "Survey",
            url: "{surveyId}/{userId}/{hash}",
            defaults: new { controller = "Home", action = "Survey" },
            constraints: new { surveyId = @"\d+", userId = @"\d+" }
        );

as that is the behavior I wanted. However when I then call

@Url.Action("Survey", "Home", new 
{ 
    userId = @Model.UserId, 
    surveyId = survey.Id, 
    hash = HashHelpers.CreateShortenedUrlSafeHash(@Model.SecretString + survey.Id.ToString() + @Model.UserId.ToString())
})

It generates

/Admin/Home/Survey?userId=25&surveyId=19&hash=2Norc

instead of a shiny path. I can force it with Url.RouteUrl but I thought it should have picked this one automatically.


Solution

  • You need to create route for each combination.

    Check this Phil Haack Article

      routes.MapRoute( 
                name: "Survey", 
                url: "{controller}/{action}/{surveyid}/{userid}/{hash}", 
                defaults: new { controller = "Home", action = "Survey" }, 
                constraints: new { surveyid = @"\d+", userid = @"\d+" } 
      );
    
      routes.MapRoute(
            name: "Survey",
            url: "{surveyid}/{userid}/{hash}",
            defaults: new { controller = "Home", action = "Survey" },
            constraints: new { surveyid = @"\d+", userid = @"\d+" }
      );
    

    Check this Route with Two optional parameters in MVC3 not working