2016-12-08 25 views
5

Napisałem aplikację przy użyciu środowiska ASP.NET MVC 5. Używam dwukierunkowego powiązania między widokami a ViewModels.Jak ręcznie powiązać dane z ModelStateDictionary z modelem prezentacji za pomocą ASP.NET MVC?

Ponieważ używam wiązania dwukierunkowego, uzyskuję korzyść z walidacji po stronie klienta i serwera, co jest fajne. Jednak, gdy wysyłam do serwera żądanie o błędzie POST, a procedura obsługi żądań zgłasza wyjątek, chcę przekierować użytkownika do metody GET.

Kiedy nastąpi przekierowanie, chcę zapisać stan modelu, aby strona wyglądała tak samo podczas wyświetlania błędów. Jestem w stanie zapisać model stanu i błędy przy użyciu ActionFilters i TempData. Jednak po przekierowaniu żądania od POST do GET stan modelu jest zapisywany jako obiekt System.Web.Mvc.ModelStateDictionary, który jest parą klucz/wartość z wszystkimi danymi wejściowymi użytkownika pochodzącymi z żądania POST.

Aby poprawnie wyświetlić stronę użytkownikowi końcowemu, należy powiązać dane w System.Web.Mvc.ModelStateDictionary z moim własnym modelem prezentacji.

Jak powiązać obiekt System.Web.Mvc.ModelStateDictionary z obiektem prezentacji?

Oto jak mój kod wygląda

[ImportModelStateFromTempData] 
public ActionResult show(int id) 
{ 

    var prsenter = new UserProfileDetailsPresenter(id); 

    ModelStateDictionary tmp = TempData["Support.ModelStateTempDataTransfer"]; 

    if(tmp != null) 
    { 
     // Some how map tmp to prsenter 
    } 

    return View(prsenter); 

} 

[HttpPost] 
[ValidateAntiForgeryToken] 
[ExportModelStateToTempData] 
public ActionResult Update(int id, DetailsPresenter model) 
{ 
    try 
    { 
     if (ModelState.IsValid) 
     { 
      var updater = new UpdateAddressServiceProvider(CurrentUser); 

      updater.Handle(model.General); 
     } 

    } 
    catch (Exception exception) 
    { 
     ModelState.AddModelError("error", exception.Message); 
    } finally 
    { 
     return new RedirectResult(Url.Action("Show", new { Id = id }) + "#General"); 
    } 
} 

Odpowiedz

4

Jeśli wystąpi błąd, nie przekierowywać tylko zwrócić View.

[HttpPost] 
[ValidateAntiForgeryToken] 
[ExportModelStateToTempData] 
public ActionResult Update(int id, DetailsPresenter model) 
{ 
    try 
    { 
     if (ModelState.IsValid) 
     { 
      var updater = new UpdateAddressServiceProvider(CurrentUser); 

      updater.Handle(model.General); 
     } 

     return new RedirectResult(Url.Action("Show", new { Id = id }) + "#General"); 
    } 
    catch (Exception exception) 
    { 
     ModelState.AddModelError("error", exception.Message); 

     // Return the named view directly, and pass in the model as it stands. 
     return View("Show", model); 
    } 
} 
+0

Widok "Pokaż" oczekuje obiektu 'UserProfileDetailsPresenter' zamiast' DetailsPresenter'. Zamiast tworzyć "UserProfileDetailsPresenter" w każdym żądaniu, raczej przekierowuję do akcji 'Index' i każę utworzyć poprawny obiekt i po prostu powiązać dane. – Jaylen

+0

Najlepiej jest, żebyś zadzwonił w obu miejscach (uznanie za posiadanie go w metodzie). Za każdym razem będziesz tworzył 'UserProfileDetailsPresenter'. To jest właściwy sposób, aby to zrobić w MVC. Nie chcesz umieszczać w bazie danych niepoprawnych, zniekształconych lub nawet potencjalnie niebezpiecznych danych. – krillgar

+0

W takim przypadku nie ma potrzeby eksportowania danych ModelStateToTempData, prawda? jaka byłaby korzyść z posiadania go? – Jaylen

Powiązane problemy