ASP.NET MVC: passaggio di parametri al controller


105

Ho un controller con un metodo di azione come segue:

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

E quando lo eseguo ricevo un errore che dice:

Il dizionario dei parametri non contiene un valore valido di tipo "System.Int32" per il parametro "firstItem". Per rendere un parametro facoltativo, il suo tipo dovrebbe essere un tipo di riferimento o un tipo Nullable.

A un certo punto ho funzionato e ho deciso di provare la funzione senza parametri. Scoprendo che il controller non era persistente ho rimesso il parametro, ora si rifiuta di riconoscere il parametro quando chiamo il metodo.

Sto usando questa sintassi dell'URL per chiamare l'azione:

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

Qualche idea sul perché dovrei ricevere questo errore e cosa devo fare per risolverlo?

Ho provato ad aggiungere un altro metodo che prende un numero intero alla classe, ma fallisce anche per lo stesso motivo. Ho provato ad aggiungerne uno che accetta una stringa e la stringa è impostata su null. Ho provato ad aggiungerne uno senza parametri e funziona bene, ma ovviamente non si adatta alle mie esigenze.

Risposte:


106

Il tuo percorso deve essere impostato sulla falsariga di {controller}/{action}/{firstItem}. Se hai lasciato il routing come predefinito {controller}/{action}/{id}nel tuo global.asax.csfile, dovrai passare id.

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

... o qualcosa di simile a quello.


44
Oppure rinomina "firstItem" in "id"
Kyle Trauberman

8
In più è mondo essere saggio per aggiungere un oggetto vincoli alla MapRoute, in questo modo: new { firstItem = @"\d" }. In questo modo accetterà solo se il parametro è un qualsiasi tipo di numero. Puoi modificare la regex come preferisci e persino limitare il numero di decimali, in questo modo: new { firstItem = @"\d{4}" }- ora può essere lungo solo 4 numeri. Modifica: esempio di MapRoute completamente modificato: jsfiddle.net/HJRgT
KristianB

86

puoi cambiare firstItem in id e funzionerà

puoi cambiare il routing su global.asax (non lo consiglio)

e, non posso credere che nessuno lo abbia menzionato, puoi chiamare:

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

In un @ Url.Action sarebbe:

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

a seconda del tipo di ciò che stai facendo, l'ultimo sarà più adatto. Inoltre dovresti considerare di non eseguire l'azione ViewStockNext e invece un'azione ViewStock con indice. (i miei 2 centesimi)


15

Per riformulare la risposta di Jarret Meyer , è necessario modificare il nome del parametro in "id" o aggiungere un percorso come questo:

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

Il motivo è che la rotta predefinita cerca solo azioni senza parametro o un parametro chiamato "id".

Modifica: Heh, non importa Jarret ha aggiunto un esempio di percorso dopo la pubblicazione.


8

oppure fallo con Route Attribute:

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

Questa proprietà potrebbe non funzionare con le versioni precedenti di MVC.
Suat Atan PhD

Inoltre, affinché funzioni, è necessario assicurarsi di aver chiamato routes.MapMvcAttributeRoutes();all'interno del RegisterRoutes(RouteCollection)metodo dell'applicazione (di solito impalcato in App_Start \ RouteConfig.cs). Potrebbe non essere presente per impostazione predefinita.
Daniel Scott

7

Headspring ha creato una bella libreria che ti permette di aggiungere alias ai tuoi parametri negli attributi dell'azione. Questo assomiglia a questo:

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

Con questo non è necessario modificare il routing solo per gestire un nome di parametro diverso. La libreria supporta anche l'applicazione più volte in modo da poter mappare diverse ortografie dei parametri (utile durante il refactoring senza interrompere l'interfaccia pubblica).

Puoi scaricarlo da Nuget e leggere l'articolo di Jeffrey Palermo su di esso qui


7

public ActionResult ViewNextItem(int? id)rende l' idintero un tipo nullable, senza bisogno di conversioni string <-> int.


3

Utilizzo della funzionalità Helper tag ASP.NET Core:

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

Ironia della sorte, la risposta più breve è la migliore (questa).

1

C'è un altro modo per farlo (descritto in maggiore dettaglio nell'esempio di Stephen Walther Pager

In sostanza, crei un collegamento nella vista:

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

In routeData è possibile specificare coppie nome / valore (ad es. RouteData ["page"] = 5) e nella funzione Index del controller i parametri corrispondenti ricevono il valore. Questo è,

public ViewResult Index(int? page)

avrà pagina passata come 5. Devo ammettere, è abbastanza insolito che la stringa ("pagina") diventi automaticamente una variabile, ma è così che MVC funziona anche in altre lingue ...


0

La ragione per il trattamento speciale di "id" è che viene aggiunto alla mappatura di rotta predefinita. Per cambiarlo, vai su Global.asax.cs e troverai la seguente riga:

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

Cambialo in:

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

0

Oppure puoi provare a cambiare il tipo di parametro in stringa, quindi convertire la stringa in un numero intero nel metodo. Sono nuovo in MVC, ma credo che tu abbia bisogno di oggetti nullable nell'elenco dei parametri, in quale altro modo il controller indicherà che non è stato fornito alcun parametro di questo tipo? Così...

public ActionResult ViewNextItem(string id)...
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.