ASP.NET MVC - Übergabe von Parametern an den Controller

105

Ich habe einen Controller mit einer Aktionsmethode wie folgt:

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

Und wenn ich es starte, erhalte ich eine Fehlermeldung:

Das Parameterwörterbuch enthält keinen gültigen Wert vom Typ 'System.Int32' für den Parameter 'firstItem'. Um einen Parameter optional zu machen, sollte sein Typ entweder ein Referenztyp oder ein Nullable-Typ sein.

Ich hatte es an einem Punkt funktioniert und ich entschied mich, die Funktion ohne Parameter zu versuchen. Als ich herausfand, dass der Controller nicht dauerhaft war, habe ich den Parameter wieder eingegeben. Jetzt weigert er sich, den Parameter zu erkennen, wenn ich die Methode aufrufe.

Ich verwende diese URL-Syntax, um die Aktion aufzurufen:

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

Irgendwelche Ideen, warum ich diesen Fehler bekommen würde und was ich tun muss, um ihn zu beheben?

Ich habe versucht, eine andere Methode hinzuzufügen, die der Klasse eine Ganzzahl hinzufügt, die aus demselben Grund ebenfalls fehlschlägt. Ich habe versucht, eine hinzuzufügen, die eine Zeichenfolge akzeptiert, und die Zeichenfolge ist auf null gesetzt. Ich habe versucht, einen ohne Parameter hinzuzufügen, und das funktioniert gut, aber natürlich entspricht es nicht meinen Anforderungen.

Seltsam
quelle

Antworten:

106

Ihr Routing muss nach dem Vorbild von eingerichtet werden {controller}/{action}/{firstItem}. Wenn Sie das Routing als Standard {controller}/{action}/{id}in Ihrer global.asax.csDatei belassen haben , müssen Sie übergeben id.

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

... oder so ähnlich.

Jarrett Meyer
quelle
44
Oder benennen Sie einfach "firstItem" in "id" um
Kyle Trauberman
8
Außerdem ist es weltweit ratsam, der MapRoute ein Einschränkungsobjekt hinzuzufügen, wie folgt : new { firstItem = @"\d" }. Auf diese Weise wird nur akzeptiert, wenn der Parameter eine beliebige Zahl ist. Sie können den regulären Ausdruck beliebig ändern und sogar die Anzahl der Dezimalstellen wie folgt begrenzen: new { firstItem = @"\d{4}" }- Jetzt kann er nur noch 4 Zahlen lang sein. Bearbeiten: Beispiel für vollständig modifizierte MapRoute: jsfiddle.net/HJRgT
KristianB
86

Sie können firstItem in id ändern und es wird funktionieren

Sie können das Routing auf global.asax ändern (das empfehle ich nicht)

und kann nicht glauben, dass niemand dies erwähnt hat, können Sie anrufen:

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

In einer @ Url.Action wäre:

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

Je nachdem, was Sie tun, ist der letzte besser geeignet. Sie sollten auch in Betracht ziehen, keine ViewStockNext-Aktion und stattdessen eine ViewStock-Aktion mit Index auszuführen. (meine 2 Cent)

Bart Calixto
quelle
15

Um die Antwort von Jarret Meyer neu zu formulieren , müssen Sie den Parameternamen in 'id' ändern oder eine Route wie die folgende hinzufügen:

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

Der Grund dafür ist, dass die Standardroute nur nach Aktionen ohne Parameter oder Parameter mit dem Namen 'id' sucht.

Bearbeiten: Heh, egal, Jarret hat nach dem Posten ein Routenbeispiel hinzugefügt.

Matt Mitchell
quelle
8

oder machen Sie es mit Route Attribute:

public class InventoryController : Controller
{
    [Route("whatever/{firstItem}")]
    public ActionResult ViewStockNext(int firstItem)
    {
        int yourNewVariable = firstItem;
        // ...
    }
}
Yar
quelle
Diese Eigenschaft funktioniert möglicherweise nicht mit älteren MVC-Versionen.
Suat Atan PhD
Damit dies funktioniert, müssen Sie außerdem sicherstellen, dass Sie routes.MapMvcAttributeRoutes();innerhalb der Anwendungsmethode aufgerufen haben RegisterRoutes(RouteCollection)(normalerweise in App_Start \ RouteConfig.cs). Es ist möglicherweise nicht standardmäßig vorhanden.
Daniel Scott
7

Headspring hat eine schöne Bibliothek erstellt, mit der Sie Ihren Parametern Aliase in Attributen der Aktion hinzufügen können. Das sieht so aus:

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

Damit müssen Sie Ihr Routing nicht ändern, nur um einen anderen Parameternamen zu verarbeiten. Die Bibliothek unterstützt auch die mehrfache Anwendung, sodass Sie mehrere Parameter buchstabieren können (praktisch beim Refactoring, ohne die öffentliche Oberfläche zu beschädigen).

Sie können es von Nuget erhalten und den Artikel von Jeffrey Palermo hier lesen

Matthew Nichols
quelle
7

public ActionResult ViewNextItem(int? id)macht die idGanzzahl zu einem nullbaren Typ, ohne dass Zeichenfolgen <-> int-Konvertierungen erforderlich sind.

Oskar Duveborn
quelle
3

Verwenden der ASP.NET Core Tag Helper-Funktion:

<a asp-controller="Home" asp-action="SetLanguage" asp-route-yourparam1="@item.Value">@item.Text</a>
Sasha Yakobchuk
quelle
Ironischerweise ist die kürzeste Antwort die beste (diese).
1

Es gibt einen anderen Weg, dies zu erreichen (ausführlicher beschrieben in Stephen Walthers Pager-Beispiel

Im Wesentlichen erstellen Sie einen Link in der Ansicht:

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

In routeData können Sie Name / Wert-Paare angeben (z. B. routeData ["Seite"] = 5), und in der Controller-Indexfunktion erhalten entsprechende Parameter den Wert. Das ist,

public ViewResult Index(int? page)

Die Seite wird als 5 übergeben. Ich muss zugeben, es ist ziemlich ungewöhnlich, dass ein String ("Seite") automatisch zu einer Variablen wird - aber so funktioniert MVC auch in anderen Sprachen ...

Felix
quelle
0

Der Grund für die spezielle Behandlung von "id" ist, dass es der Standardroutenzuordnung hinzugefügt wird. Um dies zu ändern, gehen Sie zu Global.asax.cs und Sie finden die folgende Zeile:

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

Ändern Sie es in:

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

Sie können auch versuchen, den Parametertyp in Zeichenfolge zu ändern und die Zeichenfolge dann in der Methode in eine Ganzzahl zu konvertieren. Ich bin neu in MVC, aber ich glaube, Sie benötigen nullfähige Objekte in Ihrer Parameterliste. Wie kann der Controller sonst anzeigen, dass kein solcher Parameter angegeben wurde? So...

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