ASP.NET MVC: ActionResult

Každá akční metoda (action method), tedy metoda kontroleru, se vyznačuje tím, že vrací instanci potomka abstraktní třídy System.Web.Mvc.ActionResult (dále budu namespace System.Web.Mvc vypouštět). V praxi se většinou setkáváme s tím, že akční metoda končí „return View()„, return „RedirectToRoute(„Index“)“ nebo „return RedirectToAction(„Index“)„. Logicky tedy tyto metody musí vytvořit instanci nějaké třídy odděděné od ActionResult a tuto vrátit. Výše uvedené příklady ale nejsou jediné možnosti, jak můžeme něco z akční metody vrátit a na to bych se rád podíval v tomto článku.

Abstraktní třída ActionResult obsahuje jedinou abstraktní metodu: „public abstract void ExecuteResult(ControllerContext context);„. Tato metoda je volána okamžitě po tom, co je vykonána akční metoda a provedeny všechny filtry, které se na danou metodu vztahují (ty ale mohou také přerušit provádění akční metody či pozměnit její výsledek). Pomocí této metody tedy můžeme určit, co se má po skončení akční metody provést. Standardní volání „return View()“ představuje to, co popisuje návrhový vzor MVC – tedy kontroler způsobí vytvoření pohledu. Ale máme i jiné možnosti…

Podívejme se na to, jaké třídy oddědené od ActionResult máme standardně k dispozici.

EmptyResult

Jak již název této třídy napovídá, po skončení akční metody se neprovede nic. Tato třída prostě implementuje metodu ExecuteResult prázdným tělem. Hodit se může např. tehdy, když chceme provést nějakou operaci na serveru a přitom nepotřebujeme žádný výsledek. Taková akce je typicky volána z nějakého vlastního prográmku, ne přímo z prohlížeče. De facto se jedná o webovou metodu bez výsledku, přičemž parametry předáváme v requestu, typicky v URL a Form datech.

HttpUnauthorizedResult

Tato třída není o mnoho složitejší než předchozí – v těle metody ExecuteResult se pouze zavolá „context.HttpContext.Response.StatusCode = 401;„.

RedirectResult

I operaci provedenou v této třídě lze shrnout jedním řádkem kódu: „context.HttpContext.Response.Redirect(this.Url, false);„. Pouze se provede přesměrování na danou URL bez uzavření Response.

RedirectToRouteResult

Tato třída slouží k přesměrování na nějakou akci, tedy nejprve dojde k přeložení routovacích dat do URL a následně přesměrování na tuto vypočtenou URL. Tato třída stojí za metodami RedirectToAction a RedirectToRoute třídy Controller, kterými jsem se zabýval v článku o předávání dat při přesměrování.

ContentResult

Tato třída je schopna nastavit ContentType a ContentEncoding aktuální odpovědi (Response). Dále umožňuje zapsat libovolný string do těla odpovědi.

JsonResult

Tato třída pracuje obdobně jako předchozí, pouze místo stringu předáme třídě data (typu object), která jsou následně zeserializována do stringu ve formátu JSON. Akční metoda vracející instanci této třídy je tedy typicky volána z JavaScriptu.

Microsoft.Web.Mvc.BinaryResult

Tato abstraktní třída najde uplatnění tam, kde chceme jako reakci na akční metodu vrátit nějaký soubor. Typické použití je to, že ve stránce vygenerujeme odkaz na tuto akční metodu a uživateli se po kliknutí na tento odkaz začne stahovat námi specifikovaný soubor. Zdroj obsahu souboru je záležitostí potomků této třídy, např. Microsoft.Web.Mvc.BinaryStreamResult nám umožní specifikovat jako zdroj libovolný System.IO.Stream, což je myslím pro většinu případů dostačující. Tím můžeme snadno dosáhnout např. stahování souborů, které jsou uložené v databázi bez nutnosti meziukládání souborů na disk na serveru.

ViewResult

Jako poslední třídu jsem si nechal asi tu nejdůležitější a nejčastěji používanou. Instance této třídy, resp. jejích potomků, je vracena právě z metody View třídy Controller. Výsledkem volání metody ExecuteResult této třídy je totiž vyrenderová stránka (tedy pohled), příp. část stránky (tzv. partial view – obdoba user-control).
V této metodě se děje to, že nejprve je nalezen pohled reprezentovaný rozhraním IView, které má jedinou metodu Render, a následně je tato metoda zavolána. Důležitý je ale způsob, jakým dojde k vyhledání pohledu. K tomu se totiž používá property ViewEngine (typu IViewEngine) a pokud její hodnotu nenastavíme jinak, je rovna hodnotě property ViewEngines.DefaultEngine, což je instance třídy AutoViewEngine. A to je view-engine, který projde všechny view-enginy v kolekci ViewEngines.Engines a použije výsledek prvního takového, který vrátí nenullový výsledek (tedy nalezl pohled hledaného jména).
Pokud tedy nenastavíme property ViewEngine třídy ViewResult (což metody View nedělají), projdou se všechny zaregistrované view-enginy.
A celý trik je v tom, že prohledávaná kolekce (ViewEngines.Engines) obsahuje by default pouze instanci třídy WebFormViewEngine, která hledá .aspx, .ascx a .master soubory v lokacích zadaných pomocí properties této třídy a vrací třídy implementující rozhraní IView, které při volání metody Render vyrenderují stránku, příp. user-control (.ascx).
Pokud se rozhodneme použít nějaký jiný view-engine, stačí např. vyprázdnit kolekci ViewEngines.Engines a vložit do ní instanci vlastní třídy implementující rozhraní IViewEngine. Pak bude celá aplikace používat jeden view-engine, který můžeme pohodlně změnit na jednom místě (typicky global.asax.cs).
Jiným přístupem může být to, že si napíšeme v kontroleru vlastní metody (např. CustomView), které budou vracet vracet instanci třídy ViewResult stejně jako původní metody View, ale budou nastavovat také jeho property ViewEngine. Tento přístup bych použil v případě nutnosti kombinovat více view-enginů.

P.S.: Celý článek byl napsán vůči verzi ASP.NET MVC Beta.

Zanechat odpověď

Vyplňte detaily níže nebo klikněte na ikonu pro přihlášení:

Logo WordPress.com

Komentujete pomocí vašeho WordPress.com účtu. Odhlásit /  Změnit )

Google+ photo

Komentujete pomocí vašeho Google+ účtu. Odhlásit /  Změnit )

Twitter picture

Komentujete pomocí vašeho Twitter účtu. Odhlásit /  Změnit )

Facebook photo

Komentujete pomocí vašeho Facebook účtu. Odhlásit /  Změnit )

Připojování k %s

Tento web používá Akismet na redukci spamu. Zjistěte více o tom, jak jsou data z komentářů zpracovávána.