Czy widok nie powinien sprawdzać poprawności?


10

Czytałem „ W MVC model powinien obsługiwać sprawdzanie poprawności? ”, Ponieważ byłem ciekawy, gdzie powinna znaleźć się logika sprawdzania poprawności w witrynie MVC. Jeden wiersz w górnej odpowiedzi brzmi następująco: „kontrolery powinny obsługiwać sprawdzanie poprawności, modele powinny obsługiwać weryfikację”.

Podobało mi się to, ale zastanawiałem się, dlaczego nie sprawdzalibyśmy danych w widoku z kilku powodów:

  1. Widoki zazwyczaj mają solidną obsługę sprawdzania poprawności (biblioteki JS, tagi HTML5)
  2. Widoki mogą weryfikować się lokalnie, zmniejszając we / wy sieci
  3. Interfejs użytkownika został już zaprojektowany z myślą o typie danych (kalendarze dla dat, pokrętła dla liczb), co czyni go jednym małym krokiem od weryfikacji

Sprawdzanie poprawności w więcej niż jednym miejscu jest sprzeczne z koncepcją MMC polegającą na izolowaniu obowiązków, więc „zrób to w obu przypadkach” wydaje się niewłaściwe. Czy sprawdzanie poprawności danych tylko w kontrolerze jest naprawdę dominującym podejściem?


Problemem może być fałszywa dychotomia: nie ma powodu, dla którego nie można przeprowadzić walidacji w wielu miejscach, a myślenie o sytuacji jako „jedno lub drugie” może zaciemniać twój pogląd (kalambur!) Na to pytanie . Na przykład wykonanie pewnej formy weryfikacji po stronie klienta na stronie internetowej może być bardzo przydatne, ponieważ użytkownicy otrzymują natychmiastową informację zwrotną, ale nie jest również godna zaufania, więc nie może być jedyną weryfikacją.
Miles Rout,

Odpowiedzi:


10

Nie sądzę, aby było jedno miejsce, w którym można powiedzieć, że cała walidacja powinna się udać. Wynika to z faktu, że mamy kilka różnych konkurencyjnych strategii programistycznych współpracujących ze sobą w standardowej witrynie asp.net mvc.

Po pierwsze mamy pomysł na podzielenie logiki domeny na modele, logikę „akcji” na kontrolery i wyświetlanie na widok. Jest to oparte na założeniu, że cała logika będzie miała miejsce na serwerze, a przeglądarka po prostu renderuje widok.

Następnie rozszerzamy widok przy użyciu javascript po stronie klienta. Obecnie jest to tak zaawansowane, że powszechna praktyka polega na tym, że koncepcja „jednej strony internetowej” z Jquery / knockout / angular.

Ta praktyka może być równoważna z napisaniem całej aplikacji po stronie klienta, która sama implementuje wzorzec MVC lub MVVM. Zmniejszamy widok do obiektu transferu danych, a kontroler do punktu końcowego usługi. Przeniesienie całej logiki biznesowej i interfejsu użytkownika do klienta.

Może to zapewnić lepszą obsługę, ale musisz zaufać zasadniczo niegodnemu zaufania klientowi. Dlatego nadal musisz wykonywać logikę sprawdzania poprawności na serwerze, niezależnie od tego, jak dobrze twój klient wstępnie sprawdza poprawność swoich żądań.

Ponadto często mamy wymagania dotyczące walidacji, których klient nie może wykonać. na przykład. „czy mój nowy identyfikator jest unikalny?”

Każda aplikacja tworzona w celu zapewnienia najlepszego doświadczenia / wydajności będzie musiała pożyczyć na wiele paradygmatów programistycznych i pójść na kompromis, aby osiągnąć swój cel.


4
+1 i dla podkreślenia: Nigdy nie ufaj danym opublikowanym przez klienta. Zawsze.
Machado

Jak czytam to: „sprawdzanie poprawności nie jest odosobnionym pojęciem - wszystkie części aplikacji muszą być sprawdzane względem siebie w różnych kontekstach”. Ma sens, nawet jeśli więcej pracy.
WannabeCoder

tak, ale także: „możesz mieć dwie (lub więcej) aplikacji, wszystkie o różnych wzorach”
Ewan

" den · i · grate : krytykuj niesprawiedliwie; dyskredytuj. " Nie sądzę, że używasz tego słowa poprawnie. W przeciwnym razie dobra odpowiedź.
kdbanman,

nie, o to mi chodziło
Ewan,

1

Sprawdzanie poprawności w więcej niż jednym miejscu jest sprzeczne z koncepcją MMC polegającą na izolowaniu obowiązków, więc „zrób to w obu przypadkach” wydaje się niewłaściwe.

Czy można tu wziąć pod uwagę wiele obowiązków związanych z walidacją? Jak powiedziałeś w swoim # 3:

Interfejs użytkownika został już zaprojektowany z myślą o typie danych (kalendarze dla dat, pokrętła dla liczb), co czyni go jednym małym krokiem od weryfikacji

Więc może to:

Widok : Sprawdź poprawność typu, formatu, wymagania ... podstawowa weryfikacja danych wejściowych użytkownika, która nie ma nic wspólnego z logiką biznesową. Złap wszystkie te puszyste rzeczy, zanim wygenerujemy ruch sieciowy, wysyłając żądanie serwera.

Model : Sprawdź poprawność danych biznesowych. Czy jest to wartość prawna zgodnie z regułami biznesowymi? Tak, jest to wartość liczbowa (zapewniliśmy to w widoku), ale czy ma to sens?

Tylko myśl.


1

Zakładam, że potrzebujesz potwierdzenia dla wytrwałości.

Nie tylko widok, ale także model nie powinien obsługiwać sprawdzania poprawności. Podczas moich dni w IT zdałem sobie sprawę, że DDD jest jednym ze sposobów, aby upewnić się, że faktycznie postępujesz właściwie, tj. klasy są faktycznie odpowiedzialne za to, czym powinny być.

Modele oparte na projektach opartych na domenie zawierają logikę biznesową i to wszystko. Ale nie obejmują one weryfikacji, dlaczego nie?

Załóżmy, że jesteś już tak daleko, jak używasz, Data Mapperzamiast Active Recordutrzymywać warstwę domeny. Ale nadal chcesz, aby modele były sprawdzane, więc dodajesz sprawdzanie poprawności do swojego modelu.

interface Validation
{
    public function validate();
}

class ConcreteModel extends MyModel implements Validation
{
    public function validate() { // the validation logic goes here }
}

Logika sprawdzania poprawności gwarantuje, że możesz poprawnie wstawić model do bazy danych MySQL ... Minęło kilka miesięcy i zdecydowałeś, że chcesz przechowywać Modele również w bazach danych noSQL, bazach danych, które wymagają innych reguł sprawdzania poprawności niż MySQL.

Ale masz problem, masz tylko 1 metodę sprawdzania poprawności, ale musisz zweryfikować na Model2 różne sposoby.

Modele powinny robić to, za co są odpowiedzialne , dbać o logikę biznesową i robić to dobrze. Walidacja jest związana z trwałością, a nie logiką biznesową, dlatego walidacja nie należy do modelu .

Zamiast tego powinieneś utworzyć Validators, który weźmie model do sprawdzenia w swoim konstruktorze jako parametr, zaimplementuje Validationinterfejs i użyje tych Validators do sprawdzenia poprawności twoich obiektów.

interface Validation
{
    public function validate();
}

class MySQLConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model here
    }
}

class RedisConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model with different set of rules here
    }
}

Jeśli w przyszłości zdecydujesz, że chcesz dodać kolejną metodę sprawdzania poprawności dla kolejnej warstwy trwałości (ponieważ zdecydowałeś, że Redis i MySQL nie są już właściwą drogą), po prostu utworzysz inną Validatori użyjesz IoCkontenera, aby uzyskać odpowiednią instancję na twoim config.


1

Dla wielu programistów preferowana jest metoda Fat wobec Głupich Brzydkich Kontrolerów .

Podstawową koncepcją w tekście jest

... Więc zawsze pamiętaj, że Model to nie tylko baza danych. Nawet dane uzyskane z usług internetowych można wyrazić jako model! Tak, nawet kanały Atom! Ramy, które wyrywają z wprowadzenia do Modelu, prawie nigdy nie wyjaśniają tego z góry, co tylko pogarsza nieporozumienia.

i

Widok powinien dotyczyć wyłącznie generowania i prezentacji interfejsu użytkownika, aby użytkownicy mogli komunikować zamiar modelu . Kontrolery są orkiestratorami, którzy tłumaczą dane wejściowe interfejsu użytkownika na działania w Modelu i przekazują dane wyjściowe z dowolnego widoku, który został poinformowany o Modelu (modelach), który przedstawia. Kontrolery muszą definiować zachowanie aplikacji tylko w tym sensie, że odwzorowują dane wejściowe użytkownika na wywołania w modelach, ale poza tą rolą powinno być jasne, że cała logika aplikacji jest zawarta w modelu. Kontrolery to małe stworzenia z minimalnym kodem, które po prostu przygotowują scenę i pozwalają funkcjonować w zorganizowany sposób.

Widok powinien zajmować się tylko generowaniem i prezentowaniem interfejsu użytkownika, aby użytkownicy mogli komunikować zamiary modelu . Model powinien definiować dezaktualizowane dane, więc musi również odpowiadać za sprawdzanie poprawności danych.

Rejestrując osobę, każda osoba musi mieć niepowtarzalny numer identyfikacyjny nadany przez kraj. Ta kontrola (ogólnie) odbywa się poprzez UNIQUEsprawdzenie klucza przez bazę danych. Każdy podany numer identyfikacyjny powinien spełniać pewne kroki kontrolne (suma cyfr nieparzystych powinna być równa sumie cyfr parzystych itp.). Tego rodzaju kontrole powinny być wykonywane przezModel

Administrator zbiera dane Modeli przekazuje je Viewlub odwraca, gromadzi dane użytkownika Viewi przekazuje je Model. Wszelkie ograniczenia dostępu do danych i ich weryfikacji nie powinny być dokonywane przez Controller. To on Controllerzbiera dane cookie i to on Modelsprawdza, czy jest to poprawna sesja, czy użytkownik ma dostęp do tej części aplikacji.

Viewto interfejs użytkownika, który gromadzi dane od użytkownika lub przedstawia dane użytkownikowi. Proste kontrole mogą być wykonane przez podany przez Viewużytkownika adres e-mail lub nie (dlatego można to zrobić również w widoku) IMO.

Widok jest po stronie klienta i nie powinieneś wciskać danych wejściowych użytkownika. Skrypty JavaScript mogą nie działać po stronie klienta, użytkownik może użyć odręcznych skryptów, aby je zmienić lub wyłączyć skrypt za pomocą przeglądarki. Można ustawić skrypty sprawdzania poprawności po stronie klienta, ale nigdy nie należy nigdy ich wzdłużne i uczynić prawdziwy czek na Modelwarstwie.


Żeby podkreślić, że widok dotyczy wyłącznie interfejsu użytkownika, nie oznacza to, że nie można wykonać jakiejś formy sprawdzania poprawności - udzielanie natychmiastowej informacji zwrotnej użytkownikom, gdy popełnią błąd, jest w rzeczywistości bardzo ważną częścią tego, dlaczego skrypty po stronie klienta są przydatne, w kontekście MVC stosowanego do stron internetowych.
Miles Rout,

@MilesRout w rzeczywistości mam na myśli to, że Simple checks can be done by the View like the user input e-mail address or not może nie jest to takie jasne. Ale to, co powiedziałeś, jest również dla mnie prawdą, proste i łatwe kontrole można łatwo wykonać w widoku.
FallenAngel

Nie zgadzam się z tobą.
Miles Rout,

0

Widoki powinny wykonywać walidacje dla celów ff:

  1. ) Sprawdzanie poprawności interfejsu użytkownika może zmniejszyć ruch danych na serwerze.
  2. ) obsługuje nieprawidłowe dane, zanim będzie mógł podróżować na serwerze.
  3. ), jeśli chcesz zwiększyć bezpieczeństwo, lepsza jest kombinacja frontonu i back-endu Walidacja.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.