如何在ASP.NET MVC中进行RedirectToAction而不丢失请求数据


123

使用ASP.NET MVC,在某些情况下(例如,表单提交)可能需要输入RedirectToAction

一种这样的情况是,您在提交表单后遇到验证错误,需要重定向回表单,但希望该URL反映表单的URL,而不是表单提交的操作页面。

由于我需要表单包含原始POSTed数据,为了用户方便以及验证的目的,如何将数据通过RedirectToAction()?如果使用viewData参数,则我的POST参数将更改为GETparameter。


这是一个相似的问题(在同一主题上),但与此不同。无论如何,对这个问题感兴趣的人可能仍然感兴趣:http
//stackoverflow.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get

如果发生错误,为什么不只返回相同的视图?如果模型有效,通常会调用RedirectToAction-还是我遗漏了一些东西?
niico

Answers:


81

解决方案是使用TempData属性存储所需的Request组件。

例如:

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,2010年

1
这是MVC1之前的版本(2008年)。我相信,lambda在某个阶段已被删除(有一个代码复用项目MVCContrib重新引入了它们,尽管您也可以在该阶段使用它们的helper属性:stackoverflow.com/questions/1936/…)。在mvc2中,您应该可以使用RedirectToAction(“ Form”),即以字符串形式命名,尽管我松散地记得MVC 2或3引入了类似于MVCContrib的帮助器属性(如果您热衷于搜索)。
马特·米切尔

37

请记住,TempData在会话中存储表单集合。如果您不喜欢这种行为,则可以实现新的ITempDataProvider接口,并使用其他某种机制来存储临时数据。除非您知道一个事实(通过度量和分析),否则使用Session状态会伤害您,否则我不会这样做。


13

看一下MVCContrib,您可以执行以下操作:

using MvcContrib.Filters;

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

8

还有另一种避免使用tempdata的方法。我喜欢的模式涉及为无效表单的原始渲染和重新渲染创建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个视图来处理呈现表单,重新显示值(因为表单将填充先前的值)并显示错误消息。

当发布到该动作时,如果有效,它将控制权转移到另一个动作。

我正在尝试简化此模式 当我们建立对MVC的支持时, .net验证框架简化


我也使用TempData,据我所知,解决方案Deeno的问题是,如果用户在发布无效数据后刷新页面,他们将收到“您想重新提交表单数据”确认。如MattMitchell所说,使用TempData解决方案可以消除此问题。
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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.