asp.net mvc routing id parameter

I am working on a website in asp.net mvc. I have a route

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    // Parameter defaults
);

which is the default route. And I have a method

public ActionResult ErrorPage(int errorno)
{
    return View();
}

Now if I want to run this code with http://something/mycontroller/Errorpage/1
it doesn’t work. But if I change the parameter name to id from errorno
it works.

Is it compulsory to have same parameter name for this method? Or do I need to create separate routes for such situations?

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

So, you have a parameter named errorno, and you want it to have a value from parameter id. This is obviously the binding problem.

How to solve it:

  1. create a class for model binder:

    public class ParameterBinder : IModelBinder
    {
        public string ActualParameter { get; private set; }
    
        public ParameterBinder(string actualParameter)
        {
            this.ActualParameter = actualParameter;
        }
    
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            object id = controllerContext.RouteData.Values[this.ActualParameter];
            return id;
        }
    }
    
  2. create a custom attribute for custom model binding:

    [AttributeUsage(AttributeTargets.Parameter)]
    public class BindParameterAttribute : CustomModelBinderAttribute
    {
        public string ActualParameter { get; private set; }
    
        public BindParameterAttribute(string actualParameter)
        {
            this.ActualParameter = actualParameter;
        }
    
        public override IModelBinder GetBinder()
        {
            return new ParameterBinder(this.ActualParameter);
        }
    }
    
  3. apply the new attribute to your action parameters as needed:

    public ActionResult ErrorPage(
    [BindParameter("id")]
    int errorno)
    {
        return View();
    }
    

Now your errorno will have the value, which was passed as id for your url.

Note: you can remove the paramter id from the example above, if you are sure you need it solved only for id.

Leaving this way will allow you bind other parameters too.

Solution 2

Option 1

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

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

Option 2

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

public ActionResult ErrorPage(int errorno)
{
    return View();
}

Option 3

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

public ActionResult ErrorPage(int id)
{
    int errorno = id;
    return View();
}

Solution 3

use the bind attribute prefix:

public ActionResult Customer([Bind(Prefix = "id")]string cname) {}

Solution 4

@Parminder
The default route can handle all action with one parameter “id”. And I think not every action need this parameter. So I change my default route

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

and you can add a new route:

routes.MapRoute("errorpage", "yourcontroller/errorpage/{errorno}",
    new {controller="controllername", action="errorpage"});

this just handle your controll name is “controllername”. If you want to handle all controller, you can add this:

routes.MapRoute("errorpage", "{controller}/errorpage/{errorno}",
    new {controller="controllername", action="errorpage"});

This method will create very much code in global.asax if you need a lot of custom route.

Solution 5

You could either rename the parameter in the default root (which probably is not a good idea) or rename it in the action method. Adding another root will not help because it will be the same as the default one and given an url the routing engine cannot distinguish between the two and will always take the first one in the list.

Solution 6

try to use the same name of parameter in action method as in in the route table url parameter.

global.asx

routes.MapRoute(

                        "Default", // Route name
                        "{controller}/{action}/{id}", // URL with parameters
                        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults

                );

myController

public ActionResult ErrorPage(int id)

    {
        return View();
    }

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply