2012-05-31 14 views
8

Niedawno zacząłem używać MVC i jestem trochę zawiedziony. Zamiast pomagać, ramy stają mi na drodze.Jak uzyskać kontrolę nad wiązaniem modelu?

Próbuję napisać działanie kontrolera tak (pseudo kod)

ActionResult Save(long id, string whichForm) 
{ 
    if (whichForm == "A") 
    { 
     var vm = CreateModel(Request.Form); 
     if (!TryValidate(vm)) 
      return View(vm); 
     else 
      return RedirectToRoute("Success"); 
    } 
    else .... 
} 

Zasadniczo chciałbym mieć kontrolę nad tym, kiedy moim zdaniem model jest skonstruowany i gdy jest zatwierdzone. czy to możliwe? Jak mogę zaimplementować metodę CreateModel? Zastanów się, czy mogę chcieć utworzyć kilka różnych modeli widoku w ramach tego działania kontrolera.

* Rant: Nie do końca rozumiem, dlaczego powiązanie i weryfikacja modelu widoku są mieszane razem w DefaultModelBinder. Wygląda jak zapach kodu. Szczególnie, gdy trudno jest zmienić to zachowanie.

+1

Dzięki za komentarze, czy chcesz dodać komentarz? :-) – Kugel

+0

+1 Może oni nie lubili twojego * Rant, ale masz prawo do swojej opinii i nie widzę nic złego w tym pytaniu. Jeśli pytanie skutkuje dobrymi odpowiedziami, pytanie brzmi: grzywna IMO. – AaronLS

Odpowiedz

16

Można tworzyć i wiążą się z istniejącym modelu według własnego uznania:

public ActionResult Save(long id, string whichForm) 
{ 
    if (whichForm == "A") 
    { 
     var vm = new FormAViewModel(); 

     if (!TryUpdateModel(vm)) 
      return View(vm); 
     else 
      return RedirectToRoute("Success"); 
    } 
    // else .... 
} 

You also have the option of creating your own IModelBinder, jeśli chcesz pełną kontrolę nad procesem wiążącym. Można zastąpić domyślny segregator modelu lub można zarejestrować konkretne implementacje IModelBinder dla określonych typów. Sugerowałbym jednak, że chyba że twoja logika wiązania jest prosta, prawdopodobnie będziesz chciał wyprowadzić niestandardowy segregator modelu z DefaultModelBinder i po prostu zastąpić części, które Ci się nie podobają.

Nienawidzę zostawiać komentarza z trollami, ale 9 razy na 10 powodów, dla których ktoś czuje, że dany system wchodzi na ich drodze, jest to, że nie wiedzą jeszcze, jak właściwie go używać. Here is an article with general tips on model binding.

Co do rantu: sprawdzanie poprawności i wiązanie są oddzielne, jednak domyślny mechanizm modelowania powoduje sprawdzanie poprawności. Powodem tego jest umożliwienie aplikacjom sprawnego radzenia sobie z problemami wiążącymi się z brakującymi/nieprawidłowymi/niepełnymi wartościami, zamiast pozwalać, aby wiązanie działało bezgłośnie lub zgłaszało wyjątki.

+0

Dziękuję bardzo, całkowicie przegapiłem metodę TryUpdateModel. I wierz mi, że szukałem od dłuższego czasu i przeczytałem wszystko o DefaultModelBinder i IModelBinder. Przejrzałem również kod źródłowy MVC ... – Kugel

0

Możesz wykorzystać interfejs IModelBinder i napisać kompletny niestandardowy segregator. Tutaj jest to dobrze wyjaśnione. Zasadniczo interfejs ten udostępnia metodę "BindModel", w której można kontrolować zachowanie wiązania modelu wraz z walidacją.

http://www.dotnetcurry.com/ShowArticle.aspx?ID=584

Jednak to może skomplikować sprawę i można dostać w kodzie spaghetti. Sugerowałbym prostą "Akcja na model", jeśli pasuje do ciebie. Możesz napisać coś takiego:

ActionResult SaveA(long id, AViewModel) 
{ 
     //.... Action to be conducted in case it is form A. 
} 
ActionResult SaveB(...., BViewModel) 
{ 
     //... Action to be conducted in case it is form B. 
} 


// Your view models can be structured for code reuse as well. 
class AViewModel { ... } 
class BViewModel : AViewModel { ... } 
+0

Przepraszam, ale przegapiłeś punkt mojego pytania. – Kugel

Powiązane problemy