W poprzednim wpisie przyjrzeliśmy się kontrolerom oraz ich akcjom, natomiast teraz rzucimy okiem na filtry, czyli atrybuty, które można zastosować zarówno dla każdej z akcji jak i dla całego kontrolera. Atrybuty definiują nam sposób wykonania określonych akcji. W ASP.NET MVC mamy do dyspozycji kilka typów filtrów akcji:
- Filtry autoryzacji – są wywoływane na samym początku, przed pozostałymi filtrami i akcją.
Decydują o możliwości wykonania metody po wcześniejszej autentykacji lub walidacji właściwości danego żądania. Implementują interfejs IAutorizationFilter zawierający metodę OnAuthorization. - Filtry akcji – zapewniają wykonanie dodatkowych operacji, zarówno przed jak i po wykonaniu akcji. Implementują interfejs IActionFilter, który zawiera dwie metody: OnActionExecuting i OnActionExecuted. Pierwsza z nich wykonuje się przed daną akcją, natomiast druga wykonuje się po zakończeniu akcji.
- Filtry rezultatu – opakowują wywołanie obiektu typu ActionResult. Implementują interfejs IResultFilter, który zawiera dwie metody podobnie jak interfejs dla filtrów akcji. Jedna z nich to OnResultExecuting i wykonuje się przed zwróceniem rezultatu, a druga to OnResultExecuted i wykonuje się po zwróceniu rezultatu.
- Filtry wyjątków – wykonują się gdy nastąpi nieobsłużony wyjątek gdzieś w akcji. Implementują interfejs IExceptionFilter zawierający metodę OnException.
Teraz zobaczmy jak można z tych filtrów skorzystać. Użyjemy najpierw filtra autoryzacji. Chcemy wykonać akcję tylko w momencie gdy użytkownik będzie zautoryzowany. W tym celu dekorujemy naszą metodę atrybutem [Authorize] i to wszystko.
1 2 3 4 5 |
[Authorize] public ActionResult Delete(string id) { … } |
Kolejnym zaimplementowanym filtrem, którego możemy użyć jest [HandleError], który określa sposób łapania wyjątków.
1 2 3 4 5 |
[HandleError] public ActionResult Delete(string id) { … } |
W przypadku gdy zechcemy wymusić korzystanie z połączenia po HTTPS wystarczy użyć atrybutu [RequireHttps]
1 2 3 4 5 |
[RequireHttps] public ActionResult Delete(string id) { … } |
Kolejny ważniejszy atrybut to [ValidateAntiForgeryToken], o nim była mowa w jednym z poprzednich postów o CSRF. Za jego pomocą sprawdzane są klucze (ten wygenerowany w formularzu z kluczem przesłanym w żądaniu).
1 2 3 4 5 6 7 8 9 10 11 |
[HttpPost] [Authorize] [ValidateAntiForgeryToken] public ActionResult Edit(Event @event) { if (ModelState.IsValid) { … } return View(@event); } |
Nic nie stoi na przeszkodzie, aby dodawać kilka filtrów do jednej akcji. Możemy również tworzyć własne filtry, implementując odpowiednie interfejsy.
Wspomniałem na początku, że filtry można zastosować nie tylko do konkretnych metod kontrolera, ale też do całej klasy. Można to zrobić np. w ten sposób:
1 2 3 4 |
[Authorize] public class EventsController : Controller { … |
Dzięki temu, każda akcja wymaga autoryzacji do wykonania, bez konieczności powielania atrybutu dla każdej akcji.
Oprócz wyżej wymienionych, mamy do dyspozycji jeszcze kilka innych ciekawych atrybutów takich jak:
- ValidateInput – walidacja danych wejściowych
- HttpGet – obsługa żądania GET, nie trzeba dodawać tego atrybutu, ponieważ domyślnie metoda obsługuje żądania GET
- HttpPost – obsługa żądania POST
- OutputCache – powoduje cachowanie metody, możliwe jest określenie czasu przechowywania w cachu