Artykuł

freeimages.com freeimages.com
lip 11 2014
0

Filtry rezultatu w ASP.NET MVC

W przedostatnim już odcinku cyklu o filtrach ASP.NET MVC, chciałbym Wam opowiedzieć troszkę więcej o filtrach rezultatu. Nie wiem czy dobrze przetłumaczyłem ich nazwę, ale generalnie chodzi o results filter.

Filtry tego rodzaju stoją na samym końcu łańcucha przetwarzania i mogą wywołać się tuż przed i tuż po zwróceniu rezultatu. Wydaje mi się, że nie jest to jakaś popularna grupa filtrów i nie bardzo widzę dla nich jakiś specjalne zastosowanie poza profilowaniem, bądź też ewentualną zmianą wysyłanych nagłówków.

Filtry rezultatu tworzy się równie prosto jak większość pozostałych filtrów, ale szczególnie blisko im do tych związanych z akcjami. Jak wspominałem w jednym z wcześniejszych tekstów, posiadają one wspólną klasę atrybutu, którą można rozszerzyć według potrzeb. Oczywiście nic nie stoi na przeszkodzie by stworzyć taką klasę samemu od zera rozszerzając FilterAttribute oraz implementując oba interfejsy, ale nie to jest naszym dzisiejszym celem;-)

IResultFilter

Wspomniałem we wstępie o interfejsie i w istocie nie mogło go również zabraknąć w tym przypadku. Amatorzy filtrów rezultatu będą musieli standardowo rozszerzyć klasę FilterAttribute oraz zaimplementować interfejs IResultFilter.

Interfejs podobny jest do tego znanego z filtrów akcji i również pozwala na implementację aż dwóch metod:

public interface IResultFilter
{
	void OnResultExecuting(ResultExecutingContext filterContext);
    void OnResultExecuted(ResultExecutedContext filterContext);
}

Jak już wspomniałem wcześniej, pierwsza z nich wywoływana jest tuż przed zwróceniem rezultatu, natomiast druga zostaje wywołana właśnie po rzeczonym zwrocie.

Standardowo w obu metodach mamy do czynienia z kontekstem filtru, o którym więcej poczytacie na stronach MSDN tutaj i tutaj.

Podobnie jak w przypadku filtrów akcji, tak również w tym przypadku można przekazywać dane za pomocą składowych klasy - na jedno przetwarzanie wykorzystywana jest jedna instancja filtru. Za pomocą tego filtru możliwe jest nadpisanie wybranego wcześniej rezultatu, ale tylko w pierwszej z metod!

Przykład praktyczny

Ponieważ nie do końca umiem na szybko wymyślić sensowne użycie filtrów rezultatu, pozwolę sobie pożyczyć przykład który użyłem w filtrach akcji - zmierzę czas przetwarzania rezultatu wykorzystując pierwszą z metod do uruchomienia licznika, natomiast drugą do jego zatrzymania i wydrukowania informacji na dole strony. Poniżej kod filtru:

public class ResultExampleFilterAttribute: FilterAttribute, IResultFilter
{
    private Stopwatch _timer = null;

    public void OnResultExecuting(ResultExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsLocal)
        {
            return;
        }
        _timer = new Stopwatch();
        _timer.Start();
    }

    public void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsLocal ||
            (_timer == null))
        {
            return;
        }
        _timer.Stop();
        filterContext.HttpContext.Response.Write(
            string.Format("<p>Czas przetwarzania widoku to: {0:F6} sekundy.</p>",
            _timer.Elapsed.TotalSeconds)
        );
    }
}

Jak widać, jest to bardzo zbliżona konstrukcja do tej, którą pokazałem w ubiegłym tygodniu. Tak naprawdę zmieniły się tylko nazwy poszczególnych metod oraz interfejs. Niestety w tym przypadku nie mogę zastosować tricku z ViewBag ponieważ w momencie realizacji metody OnResultExecuted - widok jest już oczywiście przetworzony.

Filtr należy jeszcze zaaplikować na metodę kontrolera. Również w tym przypadku nie ma żadnych nowości:

[ResultExampleFilterAttribute]
public ActionResult ResultTest()
{
    return View();
}

Jednym słowem nuda;-) Na szczęście zostały jeszcze filtry wyjątków. Zapewniam Was już w tym momencie, że są one duuuużo ciekawsze i znacznie bardziej użyteczne;-)

Materiały

Cykl

Data ostatniej modyfikacji: 02.08.2014, 13:23.

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus