2010-04-30 23 views
14

Estoy trabajando en un sitio web en asp.net mvc. Tengo una rutaasp.net mvc parámetro de identificación de enrutamiento

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

que es la ruta predeterminada. Y tengo un método

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

Ahora si quiero ejecutar este código con http://something/mycontroller/Errorpage/1 no funciona. Pero si cambio el nombre del parámetro a id de errorno , funciona.

¿Es obligatorio tener el mismo nombre de parámetro para este método? ¿O necesito crear rutas separadas para tales situaciones?

+1

duplicado: http://stackoverflow.com/questions/2030614/asp-net-mvc-action-parameter-naming –

Respuesta

15

tanto, usted tiene un parámetro denominado errorno, y que desea que tenga un valor de parámetro id. Este es obviamente el problema vinculante.

Cómo resolverlo:

  1. crear una clase de ligante modelo:

    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. crear un atributo personalizado para el modelo personalizado de unión:

    [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. aplicar el nuevo atributo a sus parámetros de acción según sea necesario:

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

Ahora su errorno tendrá el valor, que se pasó como id para su url.

Nota: puede eliminar el parámetro id del ejemplo anterior, si está seguro de que lo necesita solo resuelto para id.

Al salir de esta manera, también podrá vincular otros parámetros.

0

Puede cambiar el nombre del parámetro en la raíz predeterminada (que probablemente no sea una buena idea) o cambiarle el nombre en el método de acción. Agregar otra raíz no será de ayuda porque será la misma que la predeterminada y, dado un url, el motor de enrutamiento no puede distinguir entre los dos y siempre tomará el primero en la lista.

0

intente utilizar el mismo nombre de parámetro en el método de acción que en el parámetro url de la tabla de rutas.

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

sé que funciona de esta manera. pero no lo quiero – Parminder

16

Opción 1

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

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

Opción 2

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

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

Opción 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(); 
} 
1

@Parminder La ruta predeterminada puede manejar todas las acciones con un parámetro "id". Y creo que no todas las acciones necesitan este parámetro. Así que cambie de ruta por defecto

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

y se puede añadir una nueva ruta:

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

este se encarga solamente de su nombre controll es "controllername". Si desea manejar todo controlador, puede añadir lo siguiente:

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

Este método creará mucho código en global.asax si necesita una gran cantidad de ruta personalizada.

4

utilizar el prefijo atributo bind:

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