开发者

asp.net mvc routing id parameter

开发者 https://www.devze.com 2022-12-28 12:47 出处:网络
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

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 }
    // Paramet开发者_高级运维er 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?


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.


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


use the bind attribute prefix:

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


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


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.


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

精彩评论

暂无评论...
验证码 换一张
取 消