ASP.NET MVC – pasar parámetros al controlador

Tengo un controlador con un método de acción de la siguiente manera:

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

Y cuando lo ejecuto obtengo un error que dice:

El diccionario de parámetros 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 tuve trabajando 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 syntax de url para llamar a la acción:

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

¿Alguna idea de por qué recibiría este error y qué debo hacer para solucionarlo?

Intenté 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.

Su enrutamiento debe configurarse siguiendo las líneas de {controller}/{action}/{firstItem} . Si dejó el enrutamiento como el {controller}/{action}/{id} global.asax.cs en su archivo global.asax.cs , entonces deberá global.asax.cs id .

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

… O algo parecido a eso.

puedes cambiar firstItem a id y funcionará

puedes cambiar el enrutamiento en global.asax (no lo recomiendo)

y, no puedo creer que nadie haya mencionado esto, puedes llamar:

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

En un @ Url.Acción sería:

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

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

Para reformular la respuesta de Jarret Meyer , debe cambiar el nombre del parámetro a ‘id’ o agregar una ruta como esta:

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

El motivo es que la ruta predeterminada solo busca acciones sin parámetro o un parámetro llamado ‘id’.

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

Headspring creó una buena biblioteca que le permite agregar alias a sus parámetros en los atributos de 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).

Puedes obtenerlo de Nuget y leer el artículo de Jeffrey Palermo aquí

public ActionResult ViewNextItem(int? id) hace que el entero de id anulable, sin necesidad de conversiones de cadenas < -> int.

o hacerlo con el atributo de ruta:

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

Hay otra manera de lograr eso (descrito con más detalle en el ejemplo de paginador de Stephen Walther)

Esencialmente, creas un enlace en la vista:

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

En routeData puede especificar pares de nombre / valor (por ejemplo, routeData [“page”] = 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á una página aprobada como 5. Tengo que admitir que es bastante inusual que la cadena (“página”) se convierta automágicamente en una variable, pero así es como funciona MVC en otros idiomas también …

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 = "" }); 

Cambiarlo a:

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

O bien, podría intentar cambiar el tipo de parámetro por una 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? Asi que…

 public ActionResult ViewNextItem(string id)... 

Uso de la función ASP.NET Core Tag Helper:

 @item.Text