Jak przekierować działanie w ASP.NET MVC bez utraty danych żądań

Za pomocą ASP.NET MVC istnieją sytuacje (takie jak złożenie formularza), które mogą wymagać RedirectToAction.

Jedną z takich sytuacji jest napotkanie błędów walidacji po przesłaniu formularza i konieczność przekierowania z powrotem do formularza, ale chcesz, aby adres URL odzwierciedlał adres URL formularza, a nie Stronę akcji, do której przesyła.

Ponieważ wymagam, aby formularz zawierał oryginalne dane POST ed, dla wygody użytkownika, a także dla celów walidacji, Jak mogę przekazać dane przez RedirectToAction()? Jeśli Używam parametru viewData, moje parametry POST zostaną zmienione na parametry GET.

Author: SpaceDog, 2008-08-05

5 answers

Rozwiązaniem jest użycie właściwości TempData do przechowywania żądanych komponentów żądania.

Na przykład:

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

Następnie w akcji "forma" możesz przejść:

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);
}
 76
Author: Matt Mitchell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-07 00:59:36

Należy pamiętać, że TempData przechowuje kolekcję formularzy w sesji. Jeśli nie podoba Ci się to zachowanie, możesz zaimplementować nowy interfejs ITempDataProvider i użyć innego mechanizmu do przechowywania danych tymczasowych. Nie zrobiłbym tego, chyba że wiesz na pewno (poprzez pomiar i profilowanie), że korzystanie ze stanu sesji boli.

 36
Author: Haacked,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-07 05:12:32

Spójrz na MVCContrib , możesz to zrobić:

using MvcContrib.Filters;

[ModelStateToTempData]
public class MyController : Controller {
    //
    ...
}
 13
Author: Dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 16:48:19

Jest inny sposób, który pozwala uniknąć tempdata. Wzór, który lubię, polega na utworzeniu 1 akcji zarówno dla oryginalnego renderowania, jak i ponownego renderowania nieprawidłowego formularza. Chodzi o coś takiego:

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();

To wzór mniej więcej. Trochę pseudo. Dzięki temu możesz utworzyć 1 widok do obsługi renderowania formularza, ponownego wyświetlania wartości (ponieważ formularz będzie wypełniony poprzednimi wartościami) i wyświetlania komunikatów o błędach.

Kiedy delegowanie do tej akcji, jeśli jego ważność przenosi kontrola nad innym działaniem.

Staram się ułatwić ten wzór w . NET validation framework podczas budowania wsparcia dla MVC.

 8
Author: Dane O'Connor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-26 19:27:04

Jeśli chcesz przekazać dane do przekierowanej akcji, możesz użyć metody:

return RedirectToAction("ModelUpdated", new {id = 1});
// The definition of the action method like  public ActionResult ModelUpdated(int id);
 2
Author: lzlstyle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-30 08:39:03