sandeep
sandeep

Reputation: 31

MVC3 routing issue with multiple parameter

I am defining my action link like this:

 @Html.ActionLink("Visit profile By Name", "UserProfile", "User", new { UserId = 2, UserName = "Sandeep" }, null)

Which generates the link:

http://localhost:2010/User/UserProfile/Sandeep/2

If username == string.empty (as username is coming dynamically), then the link becomes

http://localhost:2010/User/UserProfile?UserId=2

But in that case I want my link like to look like this:

http://localhost:2010/User/UserProfile/2

Route table value:

       routes.MapRoute(
           "UserName", // Route name
           "User/UserProfile/{UserName}/{UserId}", // URL with parameters
           new { controller = "User", action = "UserProfile", UserName = UrlParameter.Optional, UserId = UrlParameter.Optional } // Parameter defaults
       );

Upvotes: 3

Views: 3071

Answers (3)

John Allers
John Allers

Reputation: 3122

This is simplification of Mystere Man's answer.

routes.MapRoute("UserName",
                "User/UserProfile/{UserName}/{UserId}",
                new { controller = "User", action = "UserProfile" }
);

routes.MapRoute("UserIdOnly",
                "User/UserProfile/{UserId}",
                new { controller = "User", action = "UserProfile" }
);

All you need to do is remove UrlParameter.Optional in your route and specify a second route. The reason the url looks http://localhost:2010/User/UserProfile?UserId=2 is because it is not matching your UserName route, but instead the Default route:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

I reversed the order of Mystere Man's routes and changed the UserNameId parameter to UserId. If the UserName is null or empty, it will not match the UserName route, but will match the second (UserIdOnly) route and give you the url you are looking for.

Upvotes: 0

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93464

I think what you want is to make two routes.

routes.MapRoute("UserName",                             // Route name
                "User/UserProfile/{UserNameId}", // URL with parameters
                new { controller = "User", 
                      action = "UserProfile"
);

routes.MapRoute("UserName",                             // Route name
                "User/UserProfile/{UserName}/{UserId}", // URL with parameters
                new { controller = "User", action = "UserProfile"
);

Then in your UserProfile(string userNameId) method you would check to see if userNameId is numeric, and if so then set the UserId, if not then set the UserName.

There is no real way for the route to know the difference otherwise, by default. You could use regular expressions, but there are a number of gotchas when doing that.. so it's not for the faint of heart.

You might want to add defaults if you have a mode that lists profiles if no username or id is sent.

Upvotes: 0

Praveen Prasad
Praveen Prasad

Reputation: 32117

change your route

routes.MapRoute( "UserName", // Route name 
              "User/UserProfile/{UserName}/{UserId}", // URL with parameters 
               new { 
                   controller = "User", 
                    action = "UserProfile", 
                    UserName = "UserProfile",  /*change this */
                     UserId = UrlParameter.Optional 
                  }  // Parameter defaults 
                 );

change UserName = UrlParameter.Optional to UserName = "UserProfile"

Upvotes: 3

Related Questions