2011-02-09 12 views
7

Pracuję nad tą aplikacją MVC 3 Razor i zazwyczaj wykorzystuję modele widoku dla moich widoków.Akcje kontrolera MVC - Obsługa POST i GET bez duplikatu kodu

Spora liczba moich modeli widoków zawiera więcej informacji niż tylko konkretny podmiot, z którym współpracuję w moim formularzu. Tak więc mój moduł obsługi akcji GET zainicjuje model widoku i dostarczy każdej z właściwości zamierzoną wartość itd.

W mojej procedurze obsługi POST sprawdzam, czy stan modelu jest prawidłowy, jeśli nie, ponownie wyświetlam formularz/widok z błędy.

W mojej procedurze obsługi POST musiałem skopiować kod z mojej akcji obsługi GET, aby ponownie wyświetlić widok. Jak mogę zaimplementować działania kontrolera, aby nie musieć kopiować kodu, który jest odpowiedzialny za zbieranie danych dla modelu widoku?

Próbowałem pozwolić mojej obsłudze akcji obsługiwać zarówno POST, jak i GET, ale wtedy mam parametry wejściowe, którymi można się zająć. Moja procedura obsługi POST będzie miała model widoku jako parametr wejściowy, ale dla procedury działania GET nie będzie.

+1

Czy możesz podać przykłady kodu, który właśnie piszesz? – marcind

+1

Czy próbowałeś przekierować akcję postu, aby uzyskać działanie? – frennky

Odpowiedz

4

W takich sytuacjach tworzymy konstruktorów dla naszych modeli widoków.

Spójrz na opcję 3 pod numerem this post.

+0

+1 To jest ładne i czyste podejście. –

+0

Chociaż kod, do którego się odwołuje, nie używa budowniczego zarówno w działaniach typu "pobierz i wyślij", jak bym się spodziewał na podstawie mojego pierwotnego pytania, myślę, że tworzenie builderów dla viewmodel jest dobrym rozwiązaniem. – JBeckton

-1

Twoja metoda POST powinna być w stanie podać tylko typ viewmodelu, zamiast wszystkich pojedynczych elementów danych. Jeśli viewmodel jest bardziej złożony do zbudowania, możesz chcieć napisać model modelowania dla twojego modelu widoku, który może wykonać bardziej skomplikowaną pracę (twoja metoda działania nadal bierze typ maszyny wirtualnej jako parametr).

[HttpPost] 
public ViewResult MyAction(MyViewModel model) { 
    // model should now be fully populated; check ModelState.IsValid though in case there are errors (such as the user entering "abc" for an int property) 
} 
7

Twój obsługi POST może zwrócić ActionResult z obsługi GET, jak następuje:

public ActionResult SomePageGet() { 
    var model = new SomePageViewModel(); 

    // Populate ViewModel: 
    ... 

    return View("SomePageGet", model); 
} 

[HttpPost] 
public ActionResult SomePagePost(SomePageViewModel input) { 

    // Validate the model: 
    ... 

    if (!ModelState.IsValid) { 
     // Return the GET page, with error messages: 
     return SomePageGet(); 
    } 

    return View("Success"); 
} 

Ponieważ ModelState przechowuje wszystkie komunikaty o błędach (i nieprawidłowe dane), strona GET będzie pokazać im normalnie.

0

Możesz po prostu zmienić wspólny kod w metodę rozszerzenia na głównej jednostce, nad którą pracujesz.

Następnie wywołaj go tyle razy, ile chcesz, pozostając DRY.

Nie wiem dokładnie, jaka jest funkcja tego wspólnego kodu, ale przede wszystkim będą to powiązane dane dla bogatej prezentacji. W takim przypadku rozwiązaniem, które preferuję, jest umożliwienie załadowania danych dodatkowych danych z innej akcji przy użyciu funkcji RenderAction, która później może zostać ponownie przetworzona na aktualizację strony AJAX, pozostając na DRY i rozdzielając wątpliwości dotyczące działań.

0

„... znalazłem się konieczności skopiuj kod ...”

Nie rozumiem dlaczego; dlaczego nie możesz po prostu utworzyć członka w kontrolerze i nazwać go? Nie wszystko w kontrolerze musi być akcją. Ale możesz chcieć spojrzeć na budowniczych zamiast sugerowanych @ataddeini.