sobota, 6 kwietnia 2013

ASP.NET MVC Html.Action

Dzięki metodzie Html.Action możemy w łatwy sposób generować zawartość strony przez generowanie jej części po stronie serwera.

Renderowana zawartość może być uzależniona od dodatkowych parametrów, które prześlemy do metody która generuje daną cześć.

Na początek wybieramy miejsce w którym ma zostać wyrenderowana nowa treść:

Code:
    </li>
        @Html.Action("Three")
    <li class="three">

Następnie tworzymy w kontrolerze metodę Three:

Code:
        public ActionResult Three()
        {
            return PartialView("Three");
        }

oraz widok jej odpowiadający:

Code:
Some text to render


To wszystko co jest wymagana do generowania i wyświetlania zawartości takiej metody.

Pozostaje jeszcze jedna kwestia. Jak wiadomo, każdą publiczną metodę w kontrolerze można wywołać z paska przeglądarki. Jeżeli jednak nie chcemy aby naszą metodę, która ma zostać wywołana tylko na innej strony, możemy zastosować atrybut [ChildActionOnly]:

Code:
        [ChildActionOnly]
        public ActionResult Three()
        {
            return PartialView("Three");
        }

ASP.NET MVC Sekcje

Sekcje zostały wprowadzone do ASP.NET MVC w wersji 3. Umożliwiają one wyznaczenie miejsca gdzie, zostanie załadowana dodatkowa treść.

Sekcję definiujemy w sposób bardzo prosty, np. w pliku _Layout:

Code:
@RenderSection("MySection", false)


Parametry które przekazujemy to:
  • nazwa sekcji
  • flaga oznaczająca czy dana sekcja jest wymagana
Jeżeli oznaczymy, że dana sekcja jest wymagana, a np. na którejś ze stron jej nie dodamy, zostanie wyświetlony błąd.

Po wskazaniu miejsca w którym ma zostać wyświetlona sekcja, definiujemy jej treść na poszczególnych stronach, np. na stronie Index.cshtml:

Code:
@section MySection
{
    Dodatkowe informacje o Index
}


Treść zostanie wyświetlona na stronie Index w miejscu gdzie utworzyliśmy sekcję (w moim przypadku pod logiem):


Możemy także wyświetlić w sekcji domyślny tekst, jeżeli na którejś ze stron nie zostanie zdefiniowana:

Code:
                        @if (IsSectionDefined("MySection"))
                        {
                            @RenderSection("MySection", false);
                        }
                        else
                        {
                            <label>Some default text...</label>
                        }


Tak więc stosując metodę IsSectionDefined sprawdzamy czy dana sekcja jest zdefiniowana.

poniedziałek, 1 kwietnia 2013

Walidacja ASP.NET MVC 4

O walidacji pisałem już wcześniej w kursie o ASP.NET MVC 2.
W wersji trzeciej i czwartej dodano nowe możliwości walidacji o których napiszę w tym poście.


1. Atrybuty
Atrybuty opisywałem w przypadku wersji drugiej ASP.NET MVC - nie będę więc powielał już napisanego tekstu.
Dla przypomnienia tylko w jaki sposób je dodajemy do naszego modelu:

Code:
        [StringLength(50)]
        public string FirstName { get; set; }

Dodano nowe atrybuty, wśród nich m.in: EmailAddress, Url, CreditCard, Phone, Remote, Display, DisplayFormat.

Ostatni atrybut - Remote pozwala na napisanie kodu, który wykonuje walidację po stronie serwera bez potrzeby wysyłania całego formularza do serwera. Bardzo dobry przykład ilustrujący zastosowanie tego atrybutu można znaleźć w msdn http://msdn.microsoft.com/en-us/library/gg508808%28v=vs.98%29.aspx


2. Napisanie własnego atrybutu walidacji
Jeżeli kilka właściwości w modelu wymaga tego samego sposobu walidacji, można go zamknąć w atrybucie dziedziczącym po klasie ValidationAttribute:

Code:
    public class CustomValidationAttribute : ValidationAttribute
    {
        public CustomValidationAttribute() : base("{0} is not valid")
        {
            
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            //Validacja

            return ValidationResult.Success;
        }
    }

W naszej klasie nadpisujemy metodę IsValid i umieszczamy w niej kod odpowiedzialny za walidację wartości. w przypadku powodzenia zwracamy wartość Success, w innym przypadku zwracamy obiekt ValidationResult z wiadomością błędu.


3. Interfejs IValidatableObject
Zaletą tego rozwiązania jest to, że mamy dostęp do całego obiektu modelu w momencie przeprowadzania walidacji. W przypadku atrybutów możemy przeprowadzić walidację więcej niż jednego pola na raz, jednak korzystając z interfejsu IValidatableObject jest to o wiele prostsze.
Przykład:

Code:
    public class ApplicationUser : IEditModel, IValidatableObject
    {
        public int Id { get; set; }

        [StringLength(50)]
        public string FirstName { get; set; }

        public string LastName { get; set; }
        public bool SecretField { get; set; }

        public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
        {
            if (FirstName.Length > 30 && LastName.Length > 30)
            {
                yield return new ValidationResult("Something is wrong...");
            }
        }
    }