Czy jest jakiś dobry powód, aby używać FormCollection zamiast ViewModel?

Odziedziczyłem bazę kodu napisaną w ASP.Net MVC 4. Każda metoda post zajmuje FormCollection. Oprócz uciążliwości konieczności dostępu do wartości za pomocą cytowanych łańcuchów, prowadzi to również do wad, takich jak brak możliwości używania atrybutów ModelState.IsValid lub [AllowHtml] we właściwościach My ViewModel. W rzeczywistości stworzyli klasy ViewModel dla każdego ze swoich widoków (chociaż są one w zasadzie tylko bezpośrednimi opakowaniami wokół rzeczywistych klas modelu Entity Framework), ale są one używane tylko dla GET metody.

Czy jest coś, co mi umyka w FormCollection, co daje powód, dla którego może to być dobry pomysł? Wydaje się, że ma tylko wady. Chciałbym przejść i "naprawić" to za pomocą ViewModels zamiast. Wymagałoby to sporo pracy, ponieważ ViewModels mają właściwości, które są interfejsami, a nie konkretnymi klasami, co oznacza albo pisanie niestandardowego segregatora, albo zmianę ViewModels.

Ale może jest coś, czego mi brakuje, gdy ma to sens aby użyć FormCollection?

Author: Imad Alazani, 2013-06-08

10 answers

Czy Jest jakiś dobry powód, aby używać FormCollection zamiast ViewModel?

Nie. Mam następujące problemy.

Wydanie - 1

W przypadku FormCollection jest used...It będzie obowiązkowe dla Type Cast wartości Primitive Type niekoniecznie, ponieważ podczas uzyskiwania wpisu określonego indeksu System.Collections.Specialized.NameValueCollection, zwracana wartość jest typu String. Taka sytuacja nie nastąpi w przypadku mocno wpisanego View-Models.

Wydanie - 2

Kiedy Prześlij formularz i przejdź do metody akcji Post, a View-Model ponieważ parametr istnieje w metodzie akcji, masz możliwość odesłania opublikowanych wartości do ciebie View. W przeciwnym razie napisz kod ponownie, aby wysłać go z powrotem przez TempData/ViewData/ViewBag

Tutaj wpisz opis obrazka

widok-modele są zwykłymi klasami, tworzonymi do wiązania danych z widokami

Wydanie - 3

Mamy adnotacje do danych, które można zaimplementować w View Model lub Custom Validations.

Tutaj wpisz opis obrazka

ASP.Net MVC upraszcza walidacje modeli za pomocą adnotacji danych. Adnotacje danych są atrybutami, które są stosowane nad właściwościami. Możemy utworzyć niestandardowy atrybut walidacji, dziedzicząc wbudowaną klasę atrybutu walidacji.



Wydanie - 4

Przykład masz następujący HTML

<input type="text" name="textBox1" value="harsha" customAttr1 = "MyValue" />

pytanie : Jak możemy uzyskać dostęp do wartości customAttr1 z powyższe np z wnętrza kontrolera

Answer: gdy formularz zostanie opublikowany, tylko nazwa i wartość elementów są wysyłane z powrotem do serwera.

Alternatywy : Użyj trochę jQuery, aby uzyskać niestandardowe wartości atrybutów i opublikuj je wraz z wartościami formularza do metody akcji

Inną opcją jest raczej umieszczenie tego, co masz w niestandardowych atrybutach w ukrytych kontrolkach




Dlatego zawsze wolałabym użyj View-Models

 44
Author: Imad Alazani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-07 13:44:27

Jedyną zaletą, o której myślę, jest to, że chcesz użyć automatycznie generowanego kontrolera, jeśli nie określisz modelu EF, który ma być mocno wpisany. W takim przypadku Twoje akcje tworzenia i edycji będą używać obiektu FormCollection, ponieważ jest to niezawodny, istniejący wcześniej artefakt frameworka do pracy w tym celu. Być może poprzedni programista wybrał tę opcję podczas tworzenia swoich kontrolerów i trzymał się jej, ponieważ Visual Studio musi wiedzieć, co robi :)

Ale, w rzeczywistości, nigdy nie polecam ten headstart kilka sekund. Zawsze lepiej jest budować viewmodele, polecam przyjrzeć się wysiłkom zmierzającym w tym kierunku, choćby w celach konserwacyjnych. Dzięki wiązaniu modeli i silnie wpisywanym widokom i helperom html, znacznie bardziej prawdopodobne jest zmniejszenie liczby błędów w czasie wykonywania w wyniku zmiany magicznego ciągu i nie uświadomienia sobie tego, dopóki strona nie wybuchnie.

 6
Author: Mister Epic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-18 15:57:43

Ok, widzę, że ogólny konsensus jest taki, że nie jest lubiany. Aby zaoferować inną perspektywę, zawsze lubiłem używać formcollection przekazywanej do kontrolera przy akcjach POST. Oferuje on użycie metody TryUpdateModel z kontrolera, który zmapuje kolekcję do silnie wpisanej klasy. TryUpdateModel ma również przeciążenia, które pozwalają na białą listę właściwości modelu, który chcesz zezwolić na aktualizację.

if (TryUpdateModel(viewModel, new string[] { "Name" }))
{
    //Do something
}

Nadal pozwala na Wiązanie wszystkich modeli chcesz, ale pomaga zachować coś innego niż właściwość "Nazwa" na moim viewmodel przed aktualizacją.

Możesz zobaczyć więcej o metodzie TryUpdateModel tutaj:

Http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.tryupdatemodel(v=vs. 108).aspx

 5
Author: RollemIra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-21 13:06:26

Zawsze są obejścia, aby uciec od FormCollection lol.. możesz mieć ukryte pola powiązane ze zmiennymi modelu widoku w formularzu do zawartości twojego serca.

Kolekcje formularzy w większości wynikają z lenistwa tworzenia modelu widoku, ale wciąż wymagają czasu, aby dowiedzieć się, jak uzyskać wartości z niego w kontrolerze: p

Myślę, że został po prostu stworzony na samym początku MVC jako alternatywa dla korzystania z silnie wpisywanych widoków, gdy mając bardzo proste formy-w czasach, gdy wszyscy używali ViewBag :) ... a kiedy hey go tam miał, nie mogli go tak po prostu wyjąć.

Może możesz go użyć, jeśli jesteś absolutnie pewien, że twój widok nigdy nie będzie miał więcej niż jednego formularza? Ale to nadal zły pomysł..

Nie mogę znaleźć żadnych ostatnich artykułów mówiących o jakichkolwiek zaletach zbiorów formularzy.. podczas gdy silnie wpisane widoki są wszędzie.

 2
Author: krilovich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-20 15:32:55

Tak. Czasami może się przydać. Oto przykład:

Powiedzmy, że mamy w naszym db " date_and_time_field".

W widoku Razor chcemy użyć dwóch pól formularza. Pierwszy "Date" (może z jQuery UI Datepicker). Druga "godzina".

W akcji kontrolera, tworzymy "date_and_time_field" za pomocą Request.Form["Date"] i Request.Form["Hour"].

Są inne scenariusze, w których może się to przydać:

  • Tabela krzyżowa (z checkboxami w Żyletce widok)

  • Kolekcja Request.Unvalidated().Form (może to nie jest część twojego pytania: nie chcę być off-topic)

 2
Author: Fabio S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-08 07:09:37

Domyślny segregator modelowy zrobi prawie wszystko, czego potrzebujesz. Uciekłem się do FormCollection tylko raz, aby później dowiedzieć się, jak powiązać tablice elementów w kolekcję na ViewModel.

Po prostu przejdź ViewModel . Lepiej wszędzie, z każdego powodu.

 2
Author: Chris Holmes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-11 06:51:39

Z form collection będziesz w stanie uzyskać wszystkie wartości wewnątrz formularza. Mogą być sytuacje, w których może być konieczne podanie dodatkowych wartości z formularza, które mogą nie być częścią view model.

Weźmy przykład przekazania 10 ukrytych wartości z formularza. Zbiór form ma sens.

Jedyną trudnością, z jaką możesz się zmierzyć, jest typowanie. Wszystkie elementy kolekcji formularzy, które otrzymasz, będą ciągiem znaków; może być konieczne type cast w zależności od wymagań.

Także Walidacja stanu modelu to kolejny obszar, w którym możesz zmierzyć się z wyzwaniem.

 2
Author: sudil ravindran pk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-06 09:43:15

Zawsze możesz dodać właściwości kolekcji formularzy do podpisów metod. Będą one automatycznie wypełniane przez wartości formularzy z odpowiednimi kluczami.

 1
Author: Captain Kenpachi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-20 08:27:29

Dobrze z Forms Collection {[2] } Znajdziesz szybki sposób na uzyskanie wartości formularza. W przeciwnym razie musisz utworzyć klasę, która naśladuje pola formularza, a ludzie są czasami leniwi, aby tworzyć niestandardowe klasy dla mniej ważnych / rzadko używanych formularzy.

Nie Nie ma dodatkowej korzyści (w rzeczywistości ograniczonej) zbioru formularzy w stosunku do klasy niestandardowej jako parametrów działania i należy tego unikać, gdy jest to możliwe.

 1
Author: kazimanzurrashid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-08 07:55:11

Odpowiadając na pytanie tytułowe: tak.

Są sytuacje, w których FormCollection należy użyć. Na przykład, załóżmy, że {[1] } ma właściwość implementującą relację od 1 do n (w konkretnym przypadku, TimesheetViewModel z ICollection<TimesheetEntryViewModel>), A kontroler musi przeprowadzić walidację między wpisami czasu, aby nie uzyskać kolizji czasu między czasem zakończenia wpisu a czasem rozpoczęcia następnego wpisu. Aby oznaczyć powiązany wpis błędem walidacji, jak może być indeks liniowy odzyskane?

Cóż, przy domyślnym powiązaniu modelu, wartość indeksu jest tracona w logice kontrolera. Na szczęście FormController przechowuje indeks użyty w widoku i można wykonać bardziej szczegółową walidację.

 1
Author: Cigano Morrison Mendez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-27 22:59:18