2008-10-01 19 views
87

mam kontrolera z metody działania w następujący sposób:ASP.NET MVC - przekazywania parametrów do kontrolera

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

I kiedy uruchomić go otrzymuję komunikat o błędzie informujący:

parametrach słownik nie zawiera poprawnej wartości typu "System.Int32" dla parametru "firstItem". Aby parametr był opcjonalny, jego typ powinien być albo typem referencyjnym, albo typu Nullable.

Miałem to działa w pewnym momencie i postanowiłem wypróbować funkcję bez parametrów. Odkrycie, że kontroler nie był trwały, przywracam ten parametr, teraz odmawia rozpoznania parametru, gdy wywołuję metodę.

używam tej składni url zadzwonić działania:

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

Jakieś pomysły dlaczego chciałbym uzyskać ten błąd i co muszę zrobić, aby to naprawić?

Próbowałem dodać inną metodę, która pobiera liczbę całkowitą do klasy, ale również nie powiedzie się z tego samego powodu. Próbowałem dodać jeden, który pobiera ciąg, a ciąg jest ustawiony na wartość null. Próbowałem dodać jeden bez parametrów i to działa dobrze, ale oczywiście nie będzie pasować do moich potrzeb.

Odpowiedz

94

Twoje trasy muszą być ustawione zgodnie z {controller}/{action}/{firstItem}. Jeśli opuściłeś routing jako domyślny {controller}/{action}/{id} w swoim pliku , musisz przekazać id.

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

... lub coś blisko tego.

+37

Lub po prostu zmień nazwę "firstItem" na "id" –

+8

Co więcej, mądrzej byłoby dodać obiekt ograniczeń do MapRoute, na przykład: 'new {firstItem = @" \ d "}'. W ten sposób ** przyjmie ** tylko wtedy, gdy parametr jest jakimkolwiek rodzajem liczby. Możesz modyfikować wyrażenie regularne tak jak lubisz, a nawet ograniczać liczbę miejsc dziesiętnych, tak jak to: 'new {firstItem = @" \ d {4} "}' - teraz może mieć tylko 4 cyfry. Edycja: przykład w pełni zmodyfikowanej MapRoute: http://jsfiddle.net/HJRgT/ – KristianB

15

przeformułowanie Jarret Meyer's answer, trzeba zmienić nazwę parametru na „id” lub dodać trasę tak:

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

Powodem jest domyślna trasa wygląda tylko do działań bez parametru lub parametr o nazwie 'ID'.

Edytuj: Heh, nevermind Jarret dodał przykład trasy po wysłaniu.

0

Można też spróbować zmienić typ parametru na ciąg, a następnie przekonwertować ciąg na liczbę całkowitą w metodzie. Jestem nowy w MVC, ale uważam, że potrzebujesz obiektów zerowych na liście parametrów, jak inaczej kontroler wskaże, że nie podano takiego parametru? Więc ...

public ActionResult ViewNextItem(string id)... 
7

public ActionResult ViewNextItem(int? id) czyni id liczba całkowita a zerowalne typu, nie ma potrzeby ciąg < -> int konwersje.

1

Nie ma innego sposobu, aby tego dokonać (opisany bardziej szczegółowo w Stephen Walther na Pager example

Zasadniczo można utworzyć łącze w widoku:

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

W routeData można określić nazwę par/wartość (np. routeData ["page"] = 5), a w funkcji indeksu kontrolera odpowiednie parametry otrzymują tę wartość.Oznacza to, że

public ViewResult Index(int? page) 

będzie miał strona przekazany jako 5. Muszę przyznać, że to dość niezwykłe, że ciąg („Strona”) automagicznie staje się zmienną - ale to jak MVC działa w innych językach. ..

74

można zmienić firstItem do id i będzie działać

można zmienić routing na global.asax (ja nie polecam tego)

i nie mogę uwierzyć, że nikt nie wspomniał o tym możesz zadzwonić:

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

W @ Url.Action byłoby:

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

w zależności od rodzaju, co robisz, ostatni będzie bardziej odpowiedni. Należy również wziąć pod uwagę, że nie należy wykonywać akcji ViewStockNext, a zamiast akcji ViewStock z indeksem. (my 2cents)

+4

dokładnie to, czego szukam :) thx – sasjaq

0

Powodem specjalnego traktowania "id" jest dodanie go do domyślnego mapowania trasy. Aby to zmienić, przejdź do Global.asax.cs, a znajdziesz następujący wiersz:

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

go zmienić na:

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

headspring utworzony piękny bibliotekę, która pozwala dodać aliasy do Twoje parametry w atrybutach na akcji. Wygląda to tak:

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

Dzięki temu nie trzeba zmieniać trasy, aby obsłużyć inną nazwę parametru. Biblioteka obsługuje także wielokrotne jej stosowanie, dzięki czemu można odwzorować kilka pisowni parametrów (przydatne przy refaktoryzacji bez naruszania interfejsu publicznego).

Można go pobrać z Nuget i przeczytać artykuł Jeffrey Palermo na nim here

3

lub zrobić to z atrybutów trasy:

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

Ta właściwość może nie działać ze starszymi wersjami MVC. –

0

przy użyciu ASP.NET podstawowej funkcji Tag Helper:

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