2008-10-01 32 views
87

Tengo un controlador con un método de acción de la siguiente manera:ASP.NET MVC - pasar parámetros al controlador

public class InventoryController : Controller 
{ 
    public ActionResult ViewStockNext(int firstItem) 
    { 
     // Do some stuff 
    } 
} 

Y cuando lo ejecuto me sale un error que dice:

Los parámetros diccionario no contiene un valor válido de tipo 'System.Int32' para el parámetro 'firstItem'. Para que un parámetro sea opcional, su tipo debe ser un tipo de referencia o un tipo Nullable.

Lo tenía funcionando en un punto y decidí probar la función sin parámetros. Al descubrir que el controlador no era persistente, volví a poner el parámetro, ahora se niega a reconocer el parámetro cuando llamo al método.

estoy usando esta sintaxis url para llamar a la acción:

http://localhost:2316/Inventory/ViewStockNext/11 

Cualquier idea por qué me sale este error y lo que tengo que hacer para solucionarlo?

He intentado agregar otro método que lleva un entero a la clase, pero también falla por la misma razón. He intentado agregar uno que toma una cadena, y la cadena se establece en nulo. He intentado agregar uno sin parámetros y eso funciona bien, pero por supuesto no se ajusta a mis necesidades.

Respuesta

94

Su enrutamiento debe configurarse a lo largo de las líneas de {controller}/{action}/{firstItem}. Si dejó la ruta predeterminada como {controller}/{action}/{id} en su archivo global.asax.cs, deberá pasar id.

routes.MapRoute(
    "Inventory", 
    "Inventory/{action}/{firstItem}", 
    new { controller = "Inventory", action = "ListAll", firstItem = "" } 
); 

... o algo así.

+37

O simplemente cambie el nombre de "firstItem" a "id" –

+8

Además, sea prudente agregar un objeto de restricciones al MapRoute, así: 'new {firstItem = @" \ d "}'. De esta forma, ** solo ** aceptará si el parámetro es cualquier tipo de número. Puedes modificar la expresión regular como quieras, e incluso limitar el número de decimales, como este: 'new {firstItem = @" \ d {4} "}' - ahora solo puede tener 4 números. Editar: ejemplo de MapRoute completamente modificado: http://jsfiddle.net/HJRgT/ – KristianB

15

Para reformular Jarret Meyer's answer, es necesario cambiar el nombre del parámetro a 'id' o añadir una ruta como esta:

routes.MapRoute(
     "ViewStockNext", // Route name 
     "Inventory/ViewStockNext/{firstItem}", // URL with parameters 
     new { controller = "Inventory", action = "ViewStockNext" } // Parameter defaults 
    ); 

La razón es la ruta por defecto sólo busca acciones con ningún parámetro o un parámetro llamado 'carné de identidad'.

Editar: Heh, nevermind Jarret agregó un ejemplo de ruta después de la publicación.

0

O bien, podría intentar cambiar el tipo de parámetro a cadena, luego convierta la cadena en un entero en el método. Soy nuevo en MVC, pero creo que necesita objetos nullable en su lista de parámetros, ¿de qué otro modo el controlador indicará que no se proporcionó dicho parámetro? Así que ...

public ActionResult ViewNextItem(string id)... 
7

public ActionResult ViewNextItem(int? id) hace que el número entero id un tipo anulable, sin necesidad de cuerdas < -> int conversiones.

1

hay otra manera de lograr eso (que se describe con más detalle en Stephen Walther de Pager example

En esencia, se crea un vínculo en la vista:

Html.ActionLink("Next page", "Index", routeData) 

En RouteData puede especificar pares de nombre/valor (por ejemplo, routeData ["página"] = 5), y en la función de índice del controlador los parámetros correspondientes reciben el valor.Es decir,

public ViewResult Index(int? page) 

tendrá página pasado como 5. Tengo que admitir que es bastante inusual esa cadena ("página") se convierte en automagicamente una variable - pero eso es como MVC funciona en otros idiomas también. ..

74

puede cambiar a firstItem Identificación y funcionará

puede cambiar el enrutamiento en Global.asax (yo no recomiendo que)

y, no se puede creer que nadie lo mencionó , puedes llamar:

http://localhost:2316/Inventory/ViewStockNext?firstItem=11 

En un @ Url.Action sería:

@Url.Action("ViewStockNext", "Inventory", new {firstItem=11}); 

dependiendo del tipo de lo que está haciendo, los últimos serán los más adecuados. También debería considerar no hacer la acción ViewStockNext y en su lugar una acción ViewStock con índice. (mis 2cents)

+4

esto es exactamente lo que estoy buscando :) thx – sasjaq

0

El motivo del tratamiento especial de "id" es que se agrega a la asignación de ruta predeterminada. Para cambiar esto, vaya a Global.asax.cs, y encontrará la siguiente línea:

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

Cambiar a:

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

headspring creado una bonita biblioteca que le permite añadir a los alias tus parámetros en atributos en la acción. Esto se ve así:

[ParameterAlias("firstItem", "id", Order = 3)] 
public ActionResult ViewStockNext(int firstItem) 
{ 
    // Do some stuff 
} 

Con esto no tiene que modificar su enrutamiento solo para manejar un nombre de parámetro diferente. La biblioteca también admite su aplicación varias veces para que pueda mapear varios deletreos de parámetros (útil cuando se refactoriza sin romper su interfaz pública).

Puede obtenerlo de Nuget y leer el artículo de Jeffrey Palermo en él here

3

o hacerlo con la Ruta Atributo:

public class InventoryController : Controller 
{ 
    [Route("whatever/{firstItem}")] 
    public ActionResult ViewStockNext(int firstItem) 
    { 
     int yourNewVariable = firstItem; 
     // ... 
    } 
} 
+0

Esta propiedad puede no funcionar con versiones anteriores de MVC. –

0

Uso de la función auxiliar de etiquetas ASP.NET Core:

<a asp-controller="Home" asp-action="SetLanguage" asp-route-yourparam1="@item.Value">@item.Text</a> 
Cuestiones relacionadas