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

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

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

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


person Matt Mitchell    schedule 05.08.2008    source источник
comment
Вот вопрос, похожий (по той же теме), но отличный от этого. В любом случае, это может быть интересно тем, кто интересуется этим вопросом: http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get   -  person Chris Pietschmann    schedule 24.09.2008
comment
Почему вы просто не возвращаете то же представление в случае ошибки? RedirectToAction обычно вызывается, если Модель действительна - или я что-то упустил ?!   -  person niico    schedule 29.04.2017


Ответы (6)


Решение состоит в том, чтобы использовать свойство 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);
}
person Matt Mitchell    schedule 05.08.2008
comment
RedirectToAction (a = ›a.Form ()) не компилируется для меня с использованием MVCv2, вы используете MVCv3? - person ChrisAnnODell; 16.12.2010
comment
Это было до MVC1 (2008 г.). Я полагаю, что на каком-то этапе лямбды были удалены (есть проект codeplex MVCContrib, который их повторно вводит, хотя на этом этапе вы также можете использовать их вспомогательный атрибут: stackoverflow.com/questions/1936/). В mvc2 вы должны иметь возможность использовать RedirectToAction (Form), то есть имя в виде строки, хотя я вольно помню, что MVC 2 или 3 представили вспомогательный атрибут, аналогичный тому, что в MVCContrib, если вы хотите пойти на поиск. - person Matt Mitchell; 19.12.2010

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

person Haacked    schedule 07.08.2008

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

using MvcContrib.Filters;

[ModelStateToTempData]
public class MyController : Controller {
    //
    ...
}
person Dan    schedule 05.04.2009

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

var form = new FooForm();

if (request.UrlReferrer == request.Url)
{
     // Fill form with previous request's 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, поскольку мы создаем поддержку MVC. .

person Dane O'Connor    schedule 25.08.2008
comment
Я также использую TempData, проблема, насколько я понимаю, с вашим решением Deeno заключается в том, что если бы пользователь обновил страницу после публикации недействительных данных, он бы получил сообщение «Хотите ли вы повторно отправить подтверждение данных формы». Использование решения TempData, как говорит МэттМитчелл, устраняет эту проблему. - person user10479; 16.09.2008
comment
Прохладный. Кажется, кто-то заметил эту основную идею и в превью 5. - person Matt Mitchell; 14.10.2008

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

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

TempData - это решение, которое удерживает данные от действия к действию.

Employee employee = new Employee
                {
                        EmpID = "121",
                        EmpFirstName = "Imran",
                        EmpLastName = "Ghani"
                };
                TempData["Employee"] = employee;
person Aswal    schedule 18.06.2020