Jestem ciekawy, czy można przeciążać metody kontrolera w ASP.NET MVC. Za każdym razem, gdy próbuję, pojawia się błąd poniżej. Dwie metody akceptują różne argumenty. Czy tego nie da się zrobić?
Bieżące żądanie działania „MyMethod” na kontrolerze typu „MyController” jest niejednoznaczne między następującymi metodami działania:
c#
asp.net-mvc
overloading
Papa Burgundia
źródło
źródło
Odpowiedzi:
Możesz użyć tego atrybutu, jeśli chcesz, aby kod powodował przeciążenie.
Ale będziesz musiał użyć innej nazwy akcji dla tej samej metody http (jak powiedzieli inni). W tym momencie to tylko semantyka. Wolisz mieć nazwę w swoim kodzie lub atrybucie?
Phil ma artykuł na ten temat: http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx
źródło
return View();
. Na przykład:return View("MyOverloadedName");
.Tak. Byłem w stanie to zrobić, ustawiając
HttpGet
/HttpPost
(lub równoważnyAcceptVerbs
atrybut) dla każdej metody kontrolera na coś odrębnego, tj.HttpGet
LubHttpPost
, ale nie oba jednocześnie. W ten sposób może określić na podstawie typu żądania, której metody użyć.Jedną z moich sugestii jest to, że w przypadku takim jak ten byłaby prywatna implementacja, na której polegają obie publiczne metody akcji, aby uniknąć powielania kodu.
źródło
Show()
metody mają różne podpisy. Jeśli i kiedy musisz wysłać informacje do wersji Get, Twoje wersje Get i Post kończą się tym samym podpisem, a będziesz potrzebowaćActionName
atrybutu lub jednej z innych poprawek wymienionych w tym poście.ActionNameAttribute
. W praktyce rzadko się tak zdarza.Oto coś, co możesz zrobić ... chcesz metody, która może mieć parametr, a nie ma.
Dlaczego nie spróbować tego ...
To zadziałało dla mnie ... i w tej jednej metodzie możesz faktycznie przetestować, czy masz parametr przychodzący.
Zaktualizowano, aby usunąć niepoprawną składnię zerowalną w łańcuchu i użyć domyślnej wartości parametru.
źródło
string
nie może być zerowy.)string
nie może byćnullable
; ale może byćnull
! Tak czy inaczej opublikowałem pierwszy komentarz bez szczerości.Nie, nie i nie. Idź i wypróbuj kod kontrolera poniżej, w którym mamy przeciążonego „LoadCustomer”.
Jeśli spróbujesz wywołać akcję „LoadCustomer”, pojawi się błąd, jak pokazano na poniższym rysunku.
Polimorfizm jest częścią programowania w języku C #, podczas gdy HTTP jest protokołem. HTTP nie rozumie polimorfizmu. HTTP działa na koncepcji lub adresie URL, a adres URL może mieć tylko unikalną nazwę. Dlatego HTTP nie implementuje polimorfizmu.
Aby to naprawić, musimy użyć atrybutu „ActionName”.
Tak więc teraz, jeśli wykonasz wywołanie do adresu URL „Customer / LoadCustomer”, zostanie wywołana akcja „LoadCustomer”, a ze strukturą URL „Customer / LoadCustomerByName” zostanie wywołane „LoadCustomer (string str)”.
Powyższą odpowiedź wziąłem z tego artykułu kodeproject -> Przeciążenie akcji MVC
źródło
Aby rozwiązać ten problem, możesz napisać,
ActionMethodSelectorAttribute
który badaMethodInfo
dla każdej akcji i porównuje ją z zaksięgowanymi wartościami formularza, a następnie odrzuca każdą metodę, dla której wartości formularza nie pasują (oczywiście z wyłączeniem nazwy przycisku).Oto przykład: - http://blog.abodit.com/2010/02/asp-net-mvc-ambiguous-match/
ALE to nie jest dobry pomysł.
źródło
O ile wiem, możesz mieć tylko tę samą metodę, używając różnych metod http.
to znaczy
źródło
[HttpPost]
atrybutu zamiast[AcceptVerbs("POST")]
.Osiągnąłem to za pomocą funkcji routingu atrybutów w MVC5. Wprawdzie jestem nowy w MVC od dziesięciolecia tworzenia stron internetowych przy użyciu WebForms, ale poniższe działania zadziałały dla mnie. W przeciwieństwie do przyjętej odpowiedzi pozwala to na renderowanie wszystkich przeciążonych działań przez ten sam plik widoku.
Najpierw włącz routing atrybutów w App_Start / RouteConfig.cs.
Opcjonalnie udekoruj klasę kontrolera domyślnym prefiksem trasy.
Następnie udekoruj działania kontrolera, które przeciążają się nawzajem, wspólną ścieżką i parametrami, które odpowiadają. Używając parametrów ograniczonych typem, możesz użyć tego samego formatu URI z identyfikatorami różnych typów.
Mam nadzieję, że to pomaga i nie prowadzi kogoś na złą ścieżkę. :-)
źródło
Możesz użyć jednego,
ActionResult
aby poradzić sobie z jednymPost
i drugimGet
:Przydatne, jeśli twoje
Get
iPost
metody mają pasujące podpisy.źródło
Właśnie natknąłem się na to pytanie i mimo że jest już dość stare, nadal jest bardzo aktualne. Jak na ironię, jeden poprawny komentarz w tym wątku został opublikowany przez początkującego w MVC, gdy napisał ten post. Nawet dokumenty ASP.NET nie są całkowicie poprawne. Mam duży projekt i skutecznie przeciążam metody działania.
Jeśli rozumiemy routing, poza prostym domyślnym wzorcem trasy {controller} / {action} / {id}, może być oczywiste, że działania kontrolera można odwzorować przy użyciu dowolnego unikalnego wzorca. Ktoś tutaj mówił o polimorfizmie i powiedział: „HTTP nie rozumie polimorfizmu”, ale routing nie ma nic wspólnego z HTTP. Mówiąc najprościej, jest to mechanizm dopasowywania wzorca łańcucha.
Najlepszym sposobem, aby to zadziałało, jest użycie atrybutów routingu, na przykład:
Działania te zajmą się adresami URL takimi jak
/cars/usa/new-york
i/cars/usa/texas/dallas
, które będą mapowane odpowiednio na pierwszą i drugą akcję indeksu.Analizując ten przykładowy kontroler widać, że wykracza on poza domyślny wzorzec trasy wspomniany powyżej. Domyślnie działa dobrze, jeśli struktura adresu URL dokładnie odpowiada konwencjom nazewnictwa kodu, ale nie zawsze tak jest. Kod powinien opisywać domenę, ale adresy URL często muszą iść dalej, ponieważ ich treść powinna opierać się na innych kryteriach, takich jak wymagania SEO.
Zaletą domyślnego wzorca routingu jest to, że automatycznie tworzy on unikalne trasy. Jest to wymuszane przez kompilator, ponieważ adresy URL będą pasować do unikalnych typów kontrolerów i członków. Opracowanie własnych wzorów tras będzie wymagało dokładnego przemyślenia, aby zapewnić wyjątkowość i ich działanie.
Ważna uwaga Jedną wadą jest to, że używanie routingu do generowania adresów URL dla przeciążonych akcji nie działa, gdy jest oparte na nazwie akcji, np. Przy użyciu UrlHelper.Action. Ale działa, jeśli używa się nazwanych tras, np. UrlHelper.RouteUrl. A korzystanie z nazwanych tras jest, zgodnie z dobrze szanowanymi źródłami, sposobem na zrobienie tego ( http://haacked.com/archive/2010/11/21/named-routes-to-the-rescue.aspx/ ).
Powodzenia!
źródło
Możesz użyć [ActionName („NewActionName”)], aby użyć tej samej metody o innej nazwie:
źródło
Potrzebowałem przeciążenia dla:
Było mało argumentów, w których ostatecznie to zrobiłem:
Nie jest to idealne rozwiązanie, zwłaszcza jeśli masz wiele argumentów, ale dla mnie działa dobrze.
źródło
W mojej aplikacji napotkałem ten sam problem. Bez modyfikacji żadnych informacji o metodzie podałem [ActionName („SomeMeaningfulName”)] na głowie akcji. problem rozwiązany
źródło
Utwórz metodę podstawową jako wirtualną
Utwórz przesłoniętą metodę jako przesłonięcie
Edycja: Ma to oczywiście zastosowanie tylko wtedy, gdy metoda przesłonięcia znajduje się w klasie pochodnej, która wydaje się nie być intencją PO.
źródło
Podoba mi się ta odpowiedź zamieszczona w innym wątku
Jest to używane głównie, jeśli dziedziczysz po innym kontrolerze i chcesz zastąpić akcję z kontrolera podstawowego
ASP.NET MVC - Przesłanianie akcji o różnych parametrach
źródło
Dla każdej metody kontrolera dozwolony jest tylko jeden podpis publiczny. Jeśli spróbujesz go przeładować, kompiluje się, ale pojawia się błąd działania.
Jeśli nie chcesz używać różnych czasowników (takich jak
[HttpGet]
i[HttpPost]
atrybuty), aby rozróżnić przeciążone metody (które będą działać) lub zmienić routing, pozostaje to, że możesz albo podać inną metodę o innej nazwie, albo możesz wysyłka wewnątrz istniejącej metody. Oto jak to zrobiłem:Kiedyś wpadłem w sytuację, w której musiałem zachować zgodność wsteczną. Pierwotna metoda oczekiwała dwóch parametrów, ale nowa miała tylko jeden. Przeładowanie zgodne z oczekiwaniami nie działało, ponieważ MVC nie znalazł już punktu wejścia.
Aby rozwiązać ten problem, wykonałem następujące czynności:
Utworzono jedną nową metodę publiczną, która zawierała „tylko” 2 parametry ciągu. Ten działał jako dyspozytor, tj .:
Oczywiście jest to włamanie, które należy później zreformować. Ale na razie zadziałało to dla mnie.
Możesz także utworzyć dyspozytora, takiego jak:
Widać, że UpdateAction potrzebuje 2 parametrów, a DeleteAction tylko jednego.
źródło
Przepraszam za opóźnienie. Miałem ten sam problem i znalazłem link z dobrymi odpowiedziami, czy to pomoże nowym chłopakom
Wszystkie kredyty dla strony internetowej BinaryIntellect i autorów
Zasadniczo istnieją cztery sytuacje: użycie czasowników differents , użycie routingu , oznaczenie przeciążenia za pomocą atrybutu [NoAction] i zmiana nazwy atrybutu akcji za pomocą [ActionName]
Zależy to od twoich wymagań i twojej sytuacji.
W każdym razie skorzystaj z linku:
Link: http://www.binaryintellect.net/articles/8f9d9a8f-7abf-4df6-be8a-9895882ab562.aspx
źródło
Jeśli jest to próba użycia jednej akcji GET dla kilku widoków POST dla kilku akcji z różnymi modelami, spróbuj dodać akcję GET dla każdej akcji POST, która przekierowuje do pierwszego GET, aby zapobiec 404 przy odświeżaniu.
Długie ujęcie, ale powszechny scenariusz.
źródło