Route with Two optional parameters in MVC3 not working

15,556

You're missing the parameters in your route config. In order to make this work with different parameters optional (as in Phil Haack's post), you need to define multiple routes

routes.MapRoute("UserDetail-WithStatus", 
                "UserDetail/{id}/{inSaveAction}/{status}", 
                 new
                 {
                     controller = "Admin",
                     action = "UserDetail",
                     // nothing optional 
                 }
);

routes.MapRoute("UserDetail-WithoutStatus", 
                "UserDetail/{id}/{inSaveAction}", 
                 new
                 {
                     controller = "Admin",
                     action = "UserDetail",
                     // nothing optional 
                 }
);

routes.MapRoute("UserDetail-WithoutSaveAction", 
                "UserDetail/{id}", 
                 new
                 {
                     controller = "Admin",
                     action = "UserDetail",
                     id = UrlParameter.Optional
                 }
);

And then create links with:

@Html.ActionLink("Link", "Index", "Admin", new { id = 1, inSaveAction = true, success = "success" }, null)

You'll also need to set the optional parameters as nullable, otherwise you'll get exceptions if id or inSaveAction are missing.

public ActionResult UserDetail(int? id, bool? inSaveAction, string status)
{

}
Share:
15,556
Murali Murugesan
Author by

Murali Murugesan

Working as a Senior FullStack & Cloud Developer in Stockholm, Sweden. Interested in Web stack, Application Architecture and Design, Front end development frameworks. C# Azure ASP.NET Core Angular TypeScript WebAPI micro-services Agile Domain Driven Design Clean Code TDD SQL Server Clean Coder, Passionate to build a better software!

Updated on June 04, 2022

Comments

  • Murali Murugesan
    Murali Murugesan almost 2 years

    I have a following types of url used in my Application.

    localhost/admin/userdetail/id

    localhost/admin/userdetail/id/true

    localhost/admin/userdetail/id/true/success

    Here is my Admin Controller

    bool inSaveAction, string status are optional

        [Authorize]
        public ActionResult UserDetail(string Id, bool inSaveAction, string status)
        {
        }
    
        [HttpPost, Authorize, ValidateAntiForgeryToken]
        public ActionResult SaveUserDetail(UserDetailViewModel viewModel)
        {
            User userToSave = new User();
            AdminService.UpdateUser(userToSave);
            //This is calling the above function as it sending all 3 params
            return RedirectToAction("UserDetail", new { Id = viewModel.Id, 
                               inSaveAction = true, status = "success" });
        }
    

    Below case is not working

      @Html.ActionLink("DisplayName", "UserDetail", new { id = Model.Id })
    

    In Global.asax

     routes.MapRoute("UserDetail",
                "UserDetail/{id}",
                new
                {
                    controller = "Admin",
                    action = "UserDetail",
                    id = UrlParameter.Optional
                }
             );
    

    I followed http://haacked.com/archive/2011/02/20/routing-regression-with-two-consecutive-optional-url-parameters.aspx

    How can i make inSaveAction & status as optional parameter for my UserDetail action?

  • Murali Murugesan
    Murali Murugesan over 11 years
    I Tried with the code you give. This also not working. Its not taking to the action method. Any problem in routing or action method params?
  • mfanto
    mfanto over 11 years
    I just posted an edit, you'll need to make id and inSaveAction nullable. What's not working though? I tested this and all the routes work.
  • Murali Murugesan
    Murali Murugesan over 11 years
    Thanks. status also optional only.
  • mfanto
    mfanto over 11 years
    Sorry, what do you mean? Can you verify the routes work? Set a breakpoint in your UserDetail action, and then try the urls /Admin/UserDetail/1, /Admin/UserDetail/1/true, /Admin/UserDetail/1/true/success. All should work, with the respective parameters set.
  • Murali Murugesan
    Murali Murugesan over 11 years
    In all the cases i have to pass the Id. So can we remove the last route saying optional parameter?
  • mfanto
    mfanto over 11 years
    You shouldn't need the id if you mark it nullable (int? id). The id = UrlParameter.Optional means that it's not required to match the route. So the last route will match /Admin/UserDetail and /Admin/UserDetail/id. One thing you might find helpful is Route Debugger. It'll show you which route parameters are being matched nuget.org/packages/routedebugger
  • Hamid Bahmanabady
    Hamid Bahmanabady about 10 years
    I didnot write Controller Name and page had erro,,,routes.MapRoute("MyRoute", "Learn14/{id}/{name}", new { controller="Home", action="Learn14"}); Why??