ASP.NET MVC - TempData - dobra lub zła praktyka

96

Używam AcceptVerbs metody opisanej w poście w blogu Scott Gu's Preview 5 do obsługi wpisów formularzy w ASP.NET MVC:

  • Użytkownik otrzymuje pusty formularz za pośrednictwem GET
  • Użytkownik wysyła wypełniony formularz za pośrednictwem POST do tej samej akcji
  • Akcja sprawdza poprawność danych, podejmuje odpowiednią akcję i przekierowuje do nowego widoku

Więc nie muszę używać TempData. To powiedziawszy, muszę teraz dodać krok „potwierdzania” do tego procesu i wydaje się, że wymaga on użycia TempData.

Z jakiegoś powodu mam awersję do używania TempData- że jest to coś do zaprojektowania.

Czy to w ogóle uzasadniona obawa, czy też ją wymyślam?

anonimowy
źródło
1
Rozważ ustawienie kroku „potwierdzenia” w oknie dialogowym JavaScript. Mniej podróży do serwera i nie napotkasz tego problemu.
ajma

Odpowiedzi:

26

Myślę o danych tymczasowych jako o mechanizmie „odpal i zapomnij” służącym do powiadamiania użytkownika. Wspaniale jest dać im przypomnienie czegoś, co ostatnio zrobili, ale wahałbym się, czy uczynić to wymaganym krokiem w jakimś procesie użytkownika. Powodem jest to, że jeśli odświeżą stronę, wierzę, że zniknie. Cóż, myślę, że waham się przed użyciem go, ponieważ nie jest do końca zdefiniowany, jak niezawodny jest.

Zastanawiam się, czy problem polega na tym, że akcja przekierowuje na inną stronę przed krokiem potwierdzenia. Zastanawiam się, czy zamiast tego po pierwszym przesłaniu możesz wykonać wystarczającą obróbkę, aby wygenerować okno dialogowe z potwierdzeniem, a następnie zwrócić oryginalną stronę z pytaniem potwierdzającym. Podobnie jak w przypadku walidacji, z tą różnicą, że reguła sprawdzania poprawności sprawdza, czy krok potwierdzenia został wykonany (z ukrytym interfejsem użytkownika potwierdzenia, dopóki inna walidacja nie przejdzie).

Frank Schwieterman
źródło
77

Nie trzeba mieć niechęci do TempData ... Ale jeśli nie jest używany prawidłowo, może to z pewnością wskazywać na kiepski projekt. Jeśli korzystasz z adresów URL zgodnych z REST, TempData to najlepsza metoda przesyłania wiadomości z akcji POST do akcji GET. Rozważ to:

Masz formularz pod adresem URL Produkty / Nowe. Formularz wysyła do produktów / stwórz, który weryfikuje formularz i tworzy produkt, po pomyślnym zakończeniu kontroler przekierowuje do produktów URL / 1, a w przypadku błędu przekierowuje z powrotem do produktów / Nowy, aby wyświetlić komunikaty o błędach.

Produkty / 1 to tylko standardowa akcja GET dla produktu, ale chcielibyśmy, aby pojawił się komunikat informujący, że wstawienie zakończyło się sukcesem. TempData jest do tego idealna. Dodaj wiadomość do TempData w Post Controller i dodaj trochę logiki do widoku i gotowe.

W przypadku niepowodzenia dodałem wartości wprowadzone w formCollection i zbiór komunikatów o błędach do TempData w Akcji Post i przekierowuję do początkowego Action Prodcuts / New. Dodałem logikę do widoku, aby wypełnić dane wejściowe formularza poprzednio wprowadzonymi wartościami wraz z wszelkimi komunikatami o błędach. Wydaje mi się ładne i czyste!

JasonD
źródło
1
Po co to dodatkowa praca, skoro możesz pisać bezpośrednio do Products/New? Jaką wartość Products/Createdodaje?
mpen
2
@Mark, użycie Products / Create zapobiega sytuacji, w której użytkownik kończy akcję przez postback, a następnie przy późniejszym odświeżaniu (lub zakładce i zwrocie) przypadkowo ponownie kończy akcję. Więcej informacji można znaleźć na stronie en.wikipedia.org/wiki/Post/Redirect/Get
ehdv
3
@ehdv: Ale czy to naprawdę? Po pomyślnym przekierowaniu na inną stronę, w przypadku niepowodzenia powinien wyświetlić błędy formularza i nie należy podejmować żadnych działań, więc nic nie szkodzi. Zapobiegłoby to tylko irytującej wiadomości „Czy na pewno chcesz ponownie wysłać wiadomość”, co często chcę. Myślę, że to zależy od twojego projektu, więc rozumiem, o co chodzi.
otwarte
31

Myślę, że warto wahać się przed użyciem TempData. Dane TempData są przechowywane w sesji i może to mieć dla Ciebie konsekwencje, jeśli:

  1. W tej chwili nie używasz sesji w swojej witrynie
  2. Masz system, który wymaga skalowania do wysokiej przepustowości, tj. Wolisz całkowicie uniknąć stanu sesji
  3. Nie chcesz używać plików cookie (nie wiem, jak dobrze MVC obsługuje teraz sesje bez plików cookie)

Jeśli Twoja witryna musi mieć wysoką dostępność, istnieją dodatkowe kwestie związane z zastosowaniem stanu sesji, ale wszystkie te problemy można rozwiązać.

John Rayner
źródło
16
Dane TempData nie muszą być przechowywane w sesji, chociaż jest to domyślny dostawca - prawdopodobnie dlatego nie ma go w dokumencie metody. Istnieje również dostawca plików cookie, jako przykład, jak napisać niestandardowego dostawcę.
FinnNk
3

Mam metodę GetModel, która najpierw sprawdza TempData [„model”] i zwraca to. W przeciwnym razie GetModel ładuje odpowiednie dane z bazy danych.

Oszczędza dodatkowe obciążenie z bazy danych, gdy mam akcję, która musi zwrócić inny widok, który wymaga tych samych danych modelu.

Todd Smith
źródło
Tak, natknąłem się na to: (1) sprawdź, czy rekord istnieje, jeśli jest ważny, przekieruj na stronę (2) załaduj rekord do wyświetlenia dla użytkownika. Tak więc baza danych zostaje trafiona do walidacji i do wyświetlenia. Prawie używam do tego TempData, ale mam ochotę sprawdzić opinie. Podoba mi się jednak twoja metoda, aby to powstrzymać.
anonimowy
W tym scenariuszu lepiej byłoby użyć odpowiedniego mechanizmu buforowania.
nicodemus 13
3

Sprawdź kontrolery bezsesyjne w MVC3. Okazało się, że korzystanie z sesji uniemożliwia równoległe wykonywanie żądań pojedynczego użytkownika, a tym samym prowadzi do obniżenia wydajności.

Ponieważ tempdata domyślnie używa sesji, nie będziesz mógł korzystać z tej funkcji. Możesz przełączyć się na używanie plików cookie dla danych tymczasowych, ale jest to trochę niezręczne (przynajmniej dla mnie). Wciąż czystszy niż stan widoku, więc może nie jest to taki wielki przełom.

aaimnr
źródło
2
Masz rację co do kontrolerów bezsesyjnych i TempData używa sesji. ALE POCZEKAJ! Sesja NIE jest złą rzeczą i możesz łączyć i dopasowywać Sessionless z kontrolerami sesji. Naprawdę potrzebujesz kontrolerów Session_less_, gdy wykonujesz wiele wywołań AJAX do serwera (z przeglądarki). Kiedy po prostu trafiasz na jedną stronę -w czasie- .. nie musisz być bez sesji. W rzeczywistości NIE powinno to przynosić żadnych korzyści ... ponieważ atakujesz serwer tylko RAZ. Więc jest możliwe mieszanie i dopasowywanie.
Pure.Krome
2

Dlaczego masz taką awersję? Po prostu wykonaj swoją pracę i zrób to dobrze :)

Jeśli nie podoba ci się to z powodu braku silnego typowania, zawsze możesz stworzyć opakowanie, które zapewni ci interfejs z silnym typowaniem.

maxnk
źródło
2

To jak używanie ViewData, co oznacza, że ​​prawdopodobnie nie jest to zagrożenie bezpieczeństwa. Ale wolałbym używać ViewData niż TempData. Sprawdź tutaj, aby uzyskać porównanie: http://www.squaredroot.com/2007/12/20/mvc-viewdata-vs-tempdata/

W zależności od projektu, zawsze możesz przechowywać użytkownika / koszyk lub cokolwiek potrzebujesz w tymczasowych danych w bazie danych i po prostu mieć pole „IsReady”, które wskazuje, czy jest ukończone, czy nie, dzięki czemu można je rozszerzyć na później, jeśli chcesz wziąć pamiętaj, że ludzie mogą zamknąć swoje przeglądarki.

Filip Ekberg
źródło
2
Uwaga: artykuł, do którego prowadzi link, był aktualny na swój czas, ale jest dokładny tylko dla MVC1. TempData zmieniło się dość znacząco w MVC2.
mikemanne
@mikemanne, tak. Ale odpowiedź pochodzi z końca 2008 roku. Ale może odpowiedź powinna zostać zaktualizowana?
Filip Ekberg
0

Wszystkie dobre odpowiedzi, czy spojrzałeś na to, aby przekazać wiadomości.

TempData i Session nie są najlepszym pomysłem dla architektur RESTful, ponieważ większość sesji jest przechowywana w pamięci. Więc jeśli chcesz użyć farmy serwerów, sesja użytkowników istniałaby na jednym serwerze, podczas gdy ich następne żądanie mogłoby zostać wysłane na inny serwer.

Biorąc to pod uwagę, spójrz na to użycie TempData do przekazywania wiadomości tutaj.

http://jameschambers.com/2014/06/day-14-bootstrap-alerts-and-mvc-framework-tempdata/

Mogłoby to być dostosowane do użycia podejścia opartego na ciągach zapytań, jeśli jest używane tylko do przekierowania do alertów innej strony.

Królikarnia
źródło