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


123

Використання ASP.NET MVC є ситуації (наприклад, заповнення форми) , які можуть зажадати RedirectToAction.

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

Оскільки я вимагаю, щоб форма містила вихідні POSTдані, для зручності користувача, а також для перевірки, як я можу передати ці дані через RedirectToAction()? Якщо я використовую параметр viewData, мої POSTпараметри будуть змінені на GETпараметри.


Ось питання, яке схоже (на ту саму тему), але відрізняється від цього. Так чи інакше, це може зацікавити тих, хто цікавиться цим питанням: http://stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get
Кріс Пітшманн,

Чому ви просто не повертаєте той самий погляд, якщо є помилка? RedirectToAction зазвичай викликається, якщо модель дійсна - чи я щось пропускаю ?!
niico

Відповіді:


81

Рішення полягає у використанні властивості 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);
}

1
RedirectToAction (a => a.Form ()) не компілюється для мене за допомогою MVCv2, ви використовуєте MVCv3?
ChrisAnnODell

1
Це було до MVC1 (2008). Я вважаю, що лямбдати були видалені на деякому етапі (є проект кодеклерів MVCContrib, який повторно вводить їх, хоча на цьому етапі ви також можете скористатися їх атрибутом helper: stackoverflow.com/questions/1936/… ). У mvc2 ви повинні мати можливість перейти до RedirectToAction ("Форма"), тобто назви як рядок, хоча я вільно згадую, що MVC 2 або 3 ввів атрибут helper, схожий на MVCContrib, якщо ви прагнете шукати.
Метт Мітчелл

37

Майте на увазі, що TempData зберігає колекцію форм у сеансі. Якщо вам не подобається така поведінка, ви можете реалізувати новий інтерфейс ITempDataProvider і використовувати якийсь інший механізм для зберігання тимчасових даних. Я б цього не робив, якщо ви не знаєте за фактом (за допомогою вимірювання та профілювання), що використання стану сесії шкодить вам.


13

Погляньте на MVCContrib , ви можете це зробити:

using MvcContrib.Filters;

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

8

Є ще один спосіб, який дозволяє уникнути темпдатів. Моя модель, яка мені подобається, передбачає створення 1 дії як для оригінального візуалізації, так і для повторного відтворення недійсної форми. Це щось подібне:

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.


Я також використовую TempData, проблема, наскільки я це розумію, з вашим рішенням Deeno полягає в тому, що якщо користувач повинен був оновити сторінку після публікації недійсних даних, він отримає підтвердження "Хочете повторно надіслати дані форми". Використання рішення TempData, як каже MattMitchell, усуває цю проблему.
user10479

Класно. Здається, хтось помітив цю основну ідею і за попереднім переглядом 5.
Метт Мітчелл

2

Якщо ви хочете передати дані для перенаправленої дії, метод, який ви могли використовувати:

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

0

TempData - це рішення, яке зберігає дані від дії до дії.

Employee employee = new Employee
                {
                        EmpID = "121",
                        EmpFirstName = "Imran",
                        EmpLastName = "Ghani"
                };
                TempData["Employee"] = employee;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.