Parminder
Parminder

Reputation: 3158

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?

Upvotes: 17

Views: 31851

Answers (6)

avatas
avatas

Reputation: 173

@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.

Upvotes: 1

dier
dier

Reputation: 2871

use the bind attribute prefix:

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

Upvotes: 6

Tengiz
Tengiz

Reputation: 8389

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.

Upvotes: 17

Fenton
Fenton

Reputation: 250832

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();
}

Upvotes: 16

Webking
Webking

Reputation: 1862

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();
    }

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

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.

Upvotes: 0

Related Questions