Amit Kumar February 2016

Handle Multiple action with same name in MVC

In my project there is an action

public ActionResult Lead(int leadId)
{
    return View();
}

and in the View an ActionLink was created like this

@Html.ActionLink("Old Link", "Lead", "Home", new { leadId = 7 }, null)

But after some time, to make clean URL, I have changed the name of parameter of that action

public ActionResult Lead(int id)
{
    return View();
}

And ActionLink change accordingly

@Html.ActionLink("New Link", "Lead", "Home", new { id = 5 }, null)

But old link was shared in multiple social network sites. Whenever anyone clicks on that old link, he is redirect to the page www.xyx.com/Home/Lead?leadId=7

But now in my application, no such URL exists.

To handle this problem, I was thinking of overloading, but MVC action doesn't support overloading.

I have created another Action with same name with extra parameter, and redirect to new action, but it doesn't work.

public ActionResult Lead(int leadId, int extra=0)
{
    return RedirectToAction("Lead", "Home", new { id = leadId });
}

I have found one link to handle such situation, but It is not working in my case.

ASP.NET MVC ambiguous action methods

Answers


Darin Dimitrov February 2016

One possibility to handle this would be to write a custom route:

public class MyRoute : Route
{
    public MyRoute() : base(
        "Home/Lead/{id}",
        new RouteValueDictionary(new
        {
            controller = "Home",
            action = "Lead",
            id = UrlParameter.Optional,
        }),
        new MvcRouteHandler()
    )
    {
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var rd = base.GetRouteData(httpContext);
        if (rd == null)
        {
            return null;
        }

        var leadId = httpContext.Request.QueryString["leadid"];
        if (!string.IsNullOrEmpty(leadId))
        {
            rd.Values["id"] = leadId;
        }

        return rd;
    }
}

that you will register before the default one:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add(new MyRoute());

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

and now you could only have a single action:

public ActionResult Lead(int id)
{
    return View();
}

Now both the following urls will work as expected:

  • www.xyx.com/Home/Lead/7
  • www.xyx.com/Home/Lead?leadId=7

Post Status

Asked in February 2016
Viewed 1,084 times
Voted 4
Answered 1 times

Search




Leave an answer