it-swarm.com.de

ASP.NET MVC - Übergabe von Parametern an die Steuerung

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, bekomme ich eine Fehlermeldung:

Das Parameterwörterbuch enthält keinen gültigen Wert des Typs '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 einmal am Laufen und entschied mich, die Funktion ohne Parameter auszuprobieren. Da ich herausfand, dass der Controller nicht persistent war, habe ich den Parameter wieder eingefügt. Nun weigert er sich, den Parameter zu erkennen, wenn ich die Methode aufrufe.

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

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

Irgendwelche Ideen, warum ich diese Fehlermeldung erhalten würde und was ich tun muss, um das Problem zu beheben? 

Ich habe versucht, eine andere Methode hinzuzufügen, die der Klasse eine Ganzzahl hinzufügt. Sie schlägt ebenfalls aus demselben Grund fehl. Ich habe versucht, eine hinzuzufügen, die eine Zeichenfolge benötigt, und die Zeichenfolge ist auf null gesetzt. Ich habe versucht, einen Parameter ohne Parameter hinzuzufügen, und das funktioniert gut, aber natürlich passt es nicht zu meinen Bedürfnissen.

96
Odd

Ihr Routing muss entsprechend den Anweisungen von {controller}/{action}/{firstItem} eingerichtet werden. Wenn Sie das Routing als Standardcode {controller}/{action}/{id} in Ihrer global.asax.cs-Datei belassen, müssen Sie id übergeben.

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

... oder etwas in der Nähe.

101
Jarrett Meyer

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

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

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

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

In einer @ Url.Action wäre:

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

abhängig von der Art des Vorgangs ist der Letzte geeigneter. Außerdem sollten Sie die ViewStockNext-Aktion und keine ViewStock-Aktion mit Index in Betracht ziehen. (meine 2 Cent)

76
Bart Calixto

Um Jarret Meyers Antwort umzuformulieren, müssen Sie den Parameternamen in 'id' ändern oder eine Route wie folgt hinzufügen:

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

Der Grund ist, dass die Standardroute nur nach Aktionen ohne Parameter oder nach einem Parameter namens 'id' sucht.

Edit: Heh, Nevermind Jarret hat nach dem Posten ein Routenbeispiel hinzugefügt.

15
Matt Mitchell

public ActionResult ViewNextItem(int? id) macht aus der id-Ganzzahl einen nullwertfähigen Typ, es sind keine String-Konvertierungen <-> int erforderlich.

7
Oskar Duveborn

Headspring hat eine Nice-Bibliothek erstellt, mit der Sie Ihren Parametern in den Attributen der Aktion Aliase 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, um einen anderen Parameternamen zu verwenden. Die Bibliothek unterstützt auch die mehrmalige Anwendung, sodass Sie mehrere Parameterschreibweisen zuordnen können (praktisch beim Refactoring, ohne die öffentliche Schnittstelle zu beschädigen). 

Sie können es von Nuget bekommen und Jeffrey Palermos Artikel darüber lesen hier

7
Matthew Nichols

oder mache es mit Routenattribut:

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

Es gibt einen anderen Weg, um dies zu erreichen (genauer 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 ["page"] = 5), und in der Controller-Indexfunktion erhalten die entsprechenden Parameter den Wert. Das ist,

public ViewResult Index(int? page)

habe page als 5 übergeben. Ich muss zugeben, es ist ziemlich ungewöhnlich, dass String ("page") automatisch eine Variable wird - aber so funktioniert MVC auch in anderen Sprachen ...

1
Felix

Verwenden der ASP.NET Core Tag Helper-Funktion:

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

Der Grund für die spezielle Behandlung von "id" ist, dass sie zur Standardroute 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" });
0
Aristoteles

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

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