wtorek, 17 sierpnia 2010

ASP.NET MVC 2 cz. 4 Kontrolery i akcje

Kontroler odpowiada w aplikacji MVC za logikę biznesową. Tak więc stanowi bardzo ważny pomost między dostępem do danych a ich prezentacją.

Kontroler otrzymuje z widoku dane na wiele sposobów. Niektóre:
            Request.QueryString["klucz"];
            Request.Form["IdElementu"];
            Request.Cookies["Nazwa_pliku_cookie"];
            RouteData.Values["klucz"];
            RouteData.Route;
            HttpContext.Session["klucz"];

Możliwości więc jest sporo.

Jak wygląda kwestia poszukiwania parametrów w przypadku gdy akcja wymaga np parametru int id? Otóż poszukiwania prowadzone są w następującej kolejności:
Request.QueryString
Request.Form
RouteData.Values
Każdy parametr możemy oczywiście uczynić domyślnym:
- w .NET 4.0 wymaga to jedynie napisania w definicji metody int i = 10
- dla .NET 3.5 korzystamy z atrybutu: [DefaultValue(1) int id = 10

Istnieje także bardzo silny mechanizm Bindowania. Opiszę go w szczegółach później. Jednak już teraz może mały przedsmak jego możliwości. Weźmy taką sytuację. Mamy obiekt klasy Person. Jeżeli do widoku przesyłamy go a później chcemy odegrać go (np. zmodyfikowaliśmy pole FirstName) nie trzeba mozolnie przeglądać QueryString lub też obiektów formy wystarczy taka definicja akcji:
        public ActionResult MyAction(Person p)
        {
            //Operacje na obiekcie p
            return View();
        }

Więcej o tym mechanizmie później.

Zastanówmy się jeszcze, co tak na prawdę metody kontrolera zwracają:
- widok który generuje kod HTML
- przekierowanie do innej strony
- dane binarne (plik, XML itp)

Rezultaty jakie możemy zwrócić są następujące:
ViewResult - widok
PartialViewResult - wyodrębniona część
RedirectToRouteResult - przkekierowanie do innej akcji
ContentResult - zwraca czysty tekst
FileResult - zwraca plik binarny
JavaScriptResult - zwraca kod JavaScript
HttpUnauthorizedResult - przekierowuje na stronę logowaniem
EmptyResult - nic nie zwraca
Większość programistów zwraca dla każdej akcji ActionResult który jest typem bazowym dla przedstawionych powyżej.

Tutaj jeszcze jedna uwaga: w przypadku gdy chcemy użytkownika przekierować do całkowicie innej lokalizacji (poza naszą aplikacją) zwracamy wtedy:
return Redirect("http://onet.pl");



Przekazywanie danych pomiędzy żądaniami
Aby zachować dane na czas żądania można użyć w tym celu słownika TempData. Należy pamiętać, że zachowane są one na czas tylko jednego żądania i po wykorzystaniu ich zostają automatycznie usunięte.
Domyślnie dane te przechowywane są w zmiennej Session. Można stworzyć własnego providera implementując interfejs ITempDataProvider. MVC posiada jednego gotowego providera (oprócz tego działającego na zmiennej Session) CookieTempDataProvider, który serializuje dane do pliku cookie.
Kontrolować dane tymczasowe można poprzez stosowanie metody Peak("klucz") która nie powoduje oznaczenia danych jako do usunięcia.




Własna implementacja fabryki kontrolerów
Własną implementację możemy stworzyć na dwa sposoby:
- implementując interfejs IControllerFactory
- dziedzicząc po DefaultControllerFactory
Drugie rozwiązanie ma tą zaletę, gdyż umożliwia odziedziczenie funkcjonalności, którą z pewnością i tak sami musielibyśmy wcześniej czy później zaimplementować (np. casching).
Metody które nadpisujemy:
CreateController - zwraca instancję kontrolera. Wywołuje takie metody jak: GetControllerType oraz GetControllerInstance
GetControllerType - dokonuje wyboru kontrolera do stworzenia
GetControllerInstance - zwraca zainicjowany obiekt
RelaseController - uwalnia zasoby

W większości przypadków dla potrzeb DI (Dependency Injection) wystarczy nadpisać metodę GetControllerInstance.

Aby używać nowej fabryki kontrolerów należy ją zarejestrować w pliku Global.asax.cs:
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            RegisterRoutes(RouteTable.Routes);
            ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());
        }

Brak komentarzy:

Prześlij komentarz