Как перенаправитьToAction в ASP.NET MVC без потери данных запроса

Использование ASP.NET MVC - это ситуации (например, отправка формы), для которых может потребоваться RedirectToAction.

Одна из таких ситуаций - когда вы сталкиваетесь с ошибками проверки после отправки формы и должны перенаправлять обратно в форму, но хотите, чтобы URL-адрес отображал URL-адрес формы, а не страницу действий, которую она представляет.

Поскольку мне требуется, чтобы форма содержала исходные данные POST ed, для удобства пользователя, а также для целей проверки, как я могу передавать данные через RedirectToAction()? Если я использую параметр viewData, параметры POST будут изменены на GET.

Ответ 1

Решение заключается в использовании свойства TempData для хранения требуемых компонентов запроса.

Например:

public ActionResult Send()
{
    TempData["form"] = Request.Form;
    return this.RedirectToAction(a => a.Form());
}

Затем в вашем действии "Форма" вы можете пойти:

public ActionResult Form()
{
    /* Declare viewData etc. */

    if (TempData["form"] != null)
    {
        /* Cast TempData["form"] to 
        System.Collections.Specialized.NameValueCollection 
        and use it */
    }

    return View("Form", viewData);
}

Ответ 2

Имейте в виду, что TempData хранит коллекцию форм в сеансе. Если вам не нравится это поведение, вы можете реализовать новый интерфейс ITempDataProvider и использовать другой механизм для хранения временных данных. Я бы не сделал этого, если вы не знаете, что факт (через измерение и профилирование) означает, что использование состояния сеанса причиняет вам вред.

Ответ 3

Взгляните на MVCContrib, вы можете сделать это:

using MvcContrib.Filters;

[ModelStateToTempData]
public class MyController : Controller {
    //
    ...
}

Ответ 4

Есть другой способ, который позволяет избежать tempdata. Образец, который мне нравится, включает создание 1 действия как для первоначального рендера, так и для повторной обработки недопустимой формы. Это происходит примерно так:

var form = new FooForm();

if (request.UrlReferrer == request.Url)
{
     // Fill form with previous request data
}

if (Request.IsPost())
{
     if (!form.IsValid)
     {
         ViewData["ValidationErrors"] = ...
     } else {
         // update model
         model.something = foo.something;
         // handoff to post update action
         return RedirectToAction("ModelUpdated", ... etc);
     }
}

// By default render 1 view until form is a valid post
ViewData["Form"] = form;
return View();

Что шаблон более или менее. Немного псевдом. С помощью этого вы можете создать 1 представление для обработки визуализации формы, повторного отображения значений (так как форма будет заполнена предыдущими значениями) и отображения сообщений об ошибках.

При отправке этого действия, если он действителен, он передает управление другому действию.

Я пытаюсь сделать этот шаблон легким в .NET validation framework, поскольку мы создаем поддержку MVC.

Ответ 5

Если вы хотите передать данные перенаправленному действию, метод, который вы можете использовать, это:

return RedirectToAction("ModelUpdated", new {id = 1});
// The definition of the action method like  public ActionResult ModelUpdated(int id);