wtorek, 17 sierpnia 2010

ASP.NET MVC 2 cz. 7 Model

Model czyli część logiki biznesowej naszej aplikacji. To tutaj mamy do czynienia z odbieraniem i wysyłaniem danych do bazy danych jak i interakcję z kontrolerem.

Tworząc klasy modelu warto nadawać im atrybuty. Zobaczmy na przykład:
    public class Person
    {
        public int PersonId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime BirthDate { get; set; }
        public string City { get; set; }
    }

Patrząc na definicję tej klasy można dojść do wniosku, że:
- pole id nie powinno być wyświetlane zwykłemu użytkownikowi
- korzystając z generowania automatycznego formularza nazwy FirstName są mało czytelne

Poprawić można to np. tak:
    public class Person
    {
        [HiddenInput(DisplayValue=false)]
        public int PersonId { get; set; }

        [DisplayName("First Name")]
        public string FirstName { get; set; }

        [DisplayName("Last Name")]
        public string LastName { get; set; }

        [DisplayName("Date of Birth")]
        public DateTime BirthDate { get; set; }

        public string City { get; set; }
    }

Niewielkimi nakładami pisania można znacząco podnieść jakość naszych klas, a generując automatycznie formularz za pomocą metody:
<%: Html.EditorForModel() %>

stanie się on dużo czytelniejszy dla odbiorcy.
Można także użyć innych flag jak np. [ReadOnly] - tylko do odczytu czy też [DisplatyFormat] - formatujący dany string



Binding
Bardzo rozbudowany mechanizm. Działa przede wszystkim tam gdzie akcje przyjmują parametry.
Tworząc klasy, które będą uczestniczyły w bindowaniu warto uzbroić w odpowiednie atrybuty. Bardzo istotnymi atrybutami są te, odpowiedzialne za dozwolenie danej właściwości do bindowania lub nie. Można to zrobić na dwa sposoby:
[Bind(Include="FirstName, LastName")] - czyli co będzie bindowane
[Bind(Exclude="Id")] - czyli co nie będzie bindowane
Podane rozwiązanie stosuje się dla klas:
    [Bind(Exclude="PersonId")]
    public class Person
    {
        [HiddenInput(DisplayValue=false)]
        public int PersonId { get; set; }

        [DisplayName("First Name")]
        public string FirstName { get; set; }

        [DisplayName("Last Name")]
        public string LastName { get; set; }

        [DisplayName("Date of Birth")]
        public DateTime BirthDate { get; set; }

        public string City { get; set; }
    }

jak i dla pojedyńczych akcji:
        public ActionResult Akcja([Bind(Exclude="PersonId")] Person p)
        {
            return View();
        }

Który sposób wybierzemy zależy tylko od nas i danej sytuacji.




Walidacja
Podczas żądania ModelState przechowuje informacje o obiekcie Model. Dzięki temu wiemy czy np. nie występują błędy podczas walidacji naszego modelu.
Dzięki temu jesteśmy w stanie sami dodawać błędy i odpowiednio reagować na nie:
ModelState.AddModelError("Błąd", "Zła wartość pola...");

Sprawdzenia czy aktualny model nie zawiera błędów dokonujemy poprzez właściwość IsValid. Dzięki temu możemy wprowadzić logikę renderingu odpowiedniego widoku:
            if (ModelState.IsValid)
            {
                return View("GoodWork");
            }
            else
            {
                return View();
            }

Możemy także sprawdzić pojedyńcze pole na zawartość błędu:
ModelState.IsValidField("klucz");

Oczywiście wiadomość o tym, że formularz zawiera błędy jest potrzebna zarówno nam programistom jak i użytkownikom naszej aplikacji. Bardzo łatwo możemy pokazać użytkownikowi, że formularz zawiera błędy. W widoku, w miejscu w którym chcemy zobaczyć listę błędów wprowadzamy:
<%: Html.ValidationSummary() %>

Warto w tym miejscu zaimportować domyślny arkusz stylów. Dzięki temu błędnie wprowadzone pola zostaną objęte czerwoną obwódką. Jeżeli chcemy, możemy do metody ValidationSummary przesłać łańcuch, który wyświetli nagłówek walidacji.
Jeżeli potrzebujemy, aby informacje o błędach nie pojawiały się w jednym miejscu a np. obok kontrolki w której podano złe wartości, należy skorzystać z metody:
<%: Html.ValidationMessageFor(x =>x.Field) %>




Atrybuty walidacji
Mamy dostępne następujące atrybuty, które możemy przypisać polom naszej klasy:
[Range(1,50)]
[RegularExpression("pattern")]
[Required]
[StringLength]

Wyświetlanie błędów można obsłużyć na dwa sposoby:
[Required(ErrorMessage="Pole wymagane")]
lub:
[Required(ErrorMessageResourceName="MyError", ErrorMessageResourceType="ResourceTyp")]

Drugi sposób daje nam możliwość tworzenia aplikacji wielojęzykowych korzystających z plików resource.



Tworzenie własnych atrybutów walidacji
Możemy łatwo stworzyć własne atrybuty walidacji poprzez dziedziczenie klasy ValidationAttribute i implementację metody IsValid. Ważne aby w przypadku braku zawartośći pola zwrócić null (nie mamy pewności że na atrybut nałożone jest ograniczenie Required):
    public class MyValidateAttribut : ValidationAttribute
    {
        public MyValidateAttribut()
        {
            ErrorMessage = "{0} musi być poprawnym adresem email.";
        }

        public override bool IsValid(object value)
        {
            string stringValue = value as string;
            if (stringValue != null)
                return stringValue.Contains("@");
            return true;
        }
    }



Walidacja po stronie klienta
W bardzo prosty sposób możemy wprowadzić walidację po stronie klienta:
<% Html.EnableClientValidation(); %>

Należy jeszcze dołączyć dwa pliki JavaScript obsługujące tą walidację. Najlepiej je dołączyć przed końcowy znacznikiem </body> . Pliki które należy dołączyć to: MicrosoftAjax.js oraz MicrosoftMvcValidation.js
Jeżeli chcemy mieć walidację i po stronie klienta i serwera postępujemy w następujący sposób:
    <% Html.EnableClientValidation(); %>

    <% using (Html.BeginForm())
       { %>
        <%: Html.ValidationSummary() %>  
      <% } %>

Możemy także pokazać po stronie klienta, że poprawnie wprowadził jakieś wartości w pola. Aby to uczynić należy w pliku CSS wprowadzić np:
.input-validation-valid { border: 2px solid green; }

Innym aspektem jest możliwość zezwolenia wysłania formularza od klienta do serwera pomimo blokowania go przez walidację po stronie klienta. Aby to zrobić dodajemy następujący kawałek kodu:
    <script type="text/javascript">
        document.getElementById("submit").disableValidation = true;
    </script>

Brak komentarzy:

Prześlij komentarz