Недопустимое состояние модели с частичными представлениями

#asp.net-mvc-3 #validation #partial-views #t4mvc

#asp.net-mvc-3 #валидация #частичные представления #t4mvc

Вопрос:

У меня есть следующее действие

 [GET("Foo")]
public virtual ActionResult Foo()
{
    return View(new FooViewModel());
}
 

представление для этого действия вызывает это частичное представление

 @{ Html.RenderAction(MVC.FooBar.AddFoo()); }
 

с помощью действий контроллера

 [ChildActionOnly]
[GET("Foo/Add")]
public virtual ActionResult AddFoo()
{
    var viewModel = new AddFooViewModel();

    return PartialView(viewModel);
}

[POST("Foo/Add")]
public virtual ActionResult AddFooPost(AddFooViewModel viewModel)
{
    // If ModelState is invalid, how do I redirect back to /Foo 
    // with the AddFooViewModel ModelState intact??
    if (!ModelState.IsValid)
        return MVC.FooBar.Foo();

    // ... persist changes and redirect
    return RedirectToAction(MVC.FooBar.Foo());
}
 

Если кто-то отправляет форму AddFoo с ошибками ModelState, я хочу, чтобы действие POST перенаправлялось обратно в /Foo и показывало частичное представление AddFoo с ошибками ModelState. Каков наилучший подход к решению этой проблемы?

Ответ №1:

Я думаю, вы могли бы добиться этого двумя способами:

  1. Использование состояния сеанса
  2. Передача ваших данных с использованием параметров строки запроса

Я предпочитаю второй вариант.

Ответ №2:

В итоге я ввел viewmodel TempData вот так с ModelStateToTempData атрибутом на контроллере

 [ChildActionOnly]
[GET("Foo/Add")]
public virtual ActionResult AddFoo()
{
    var viewModel = TempData["AddFooViewModel"] as AddFooViewModel ?? new AddFooViewModel();

    return PartialView(viewModel);
}

[POST("Foo/Add")]
public virtual ActionResult AddFooPost(AddFooViewModel viewModel)
{
    // If ModelState is invalid, how do I redirect back to /Foo 
    // with the AddFooViewModel ModelState intact??
    if (!ModelState.IsValid)
    {
        TempData["AddFooViewModel"] = viewModel;
        return RedirectToAction(MVC.FooBar.Foo());
    }

    // ... persist changes and redirect
    return RedirectToAction(MVC.FooBar.Foo());
}