web-dev-qa-db-fra.com

ASP.NET MVC - transmission de paramètres au contrôleur

J'ai un contrôleur avec une méthode d'action comme suit:

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

Et quand je le lance, je reçois une erreur disant:

Le dictionnaire de paramètres ne contient pas de valeur valide de type 'System.Int32' pour le paramètre 'firstItem'. Pour rendre un paramètre facultatif, son type doit être soit un type de référence, soit un type Nullable.

Je l'ai eu à un moment donné et j'ai décidé d'essayer la fonction sans paramètres. Constatant que le contrôleur n'était pas persistant, j'ai remis le paramètre, mais il refuse maintenant de le reconnaître lorsque j'appelle la méthode.

J'utilise cette syntaxe d'URL pour appeler l'action:

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

Des idées pour lesquelles je voudrais obtenir cette erreur et ce que je dois faire pour la réparer? 

J'ai essayé d'ajouter une autre méthode qui prend un entier dans la classe et qui échoue pour la même raison. J'ai essayé d'ajouter un qui prend une chaîne, et la chaîne est définie sur null. J'ai essayé d'en ajouter un sans paramètre et cela fonctionne bien, mais bien sûr, cela ne répondra pas à mes besoins.

96
Odd

Votre routage doit être configuré selon les lignes de {controller}/{action}/{firstItem}. Si vous avez laissé le routage en tant que {controller}/{action}/{id} par défaut dans votre fichier global.asax.cs, vous devrez alors transmettre id.

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

... Ou quelque chose proche de cela.

101
Jarrett Meyer

vous pouvez changer firstItem en id et cela fonctionnera

vous pouvez changer le routage sur global.asax (je ne le recommande pas)

et, je ne peux pas croire que personne n'en a parlé, vous pouvez appeler:

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

Dans un @ Url.Action serait:

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

en fonction du type de ce que vous faites, le dernier sera plus approprié . Vous devriez également envisager de ne pas effectuer l'action ViewStockNext et plutôt une action ViewStock avec index. (mes 2cents)

76
Bart Calixto

Pour reformuler La réponse de Jarret Meyer, vous devez changer le nom du paramètre en 'id' ou ajouter une route comme celle-ci:

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

La raison en est que la route par défaut ne recherche que les actions sans paramètre ou un paramètre appelé "id".

Edit: Heh, Nevermind Jarret a ajouté un exemple d'itinéraire après avoir posté.

15
Matt Mitchell

public ActionResult ViewNextItem(int? id) transforme le id entier en un type nullable, inutile de convertir la chaîne <-> int.

7
Oskar Duveborn

Headspring a créé une bibliothèque Nice qui vous permet d’ajouter des alias à vos paramètres dans les attributs de l’action. Cela ressemble à ceci:

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

Avec cela, vous n'avez pas à modifier votre routage pour gérer un nom de paramètre différent. La bibliothèque prend également en charge son application plusieurs fois pour vous permettre de mapper plusieurs orthographes de paramètres (pratique lors du refactoring sans casser votre interface publique). 

Vous pouvez l'obtenir de Nuget et lire l'article de Jeffrey Palermo à ce sujet ici

7
Matthew Nichols

ou le faire avec Route Attribute:

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

Il existe un autre moyen d’y parvenir (décrit plus en détail dans Stephen Walther/ Exemple de pager

En gros, vous créez un lien dans la vue:

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

Dans routeData, vous pouvez spécifier des paires nom/valeur (par exemple, routeData ["page"] = 5) et les paramètres correspondants de la fonction Index du contrôleur reçoivent la valeur. C'est,

public ViewResult Index(int? page)

page sera passé par 5. Je dois admettre qu'il est assez inhabituel que string ("page") devienne automatiquement une variable - mais c'est comme ça que MVC fonctionne aussi dans d'autres langues ...

1
Felix

Utilisation de la fonctionnalité ASP.NET Core Tag Helper:

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

La raison du traitement spécial de "id" est son ajout au mappage de route par défaut. Pour changer cela, allez à Global.asax.cs, et vous trouverez la ligne suivante:

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

Changez le en:

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

Vous pouvez également essayer de changer le type de paramètre en chaîne, puis convertir la chaîne en entier dans la méthode. Je suis nouveau dans MVC, mais je pense que vous avez besoin d'objets nullables dans votre liste de paramètres. Comment le contrôleur peut-il indiquer sinon qu'aucun paramètre de ce type n'a été fourni? Alors...

public ActionResult ViewNextItem(string id)...
0
RAL