使用ASP.NET MVC时,可能需要RedirectToAction的情况(例如,表单提交)。
一种这样的情况是,您在提交表单后遇到验证错误,并且需要重定向回表单,但希望该URL反映表单的URL,而不是表单提交的操作页面。
为了方便用户以及进行验证,我要求表单包含原始的POST数据,如何将数据通过RedirectToAction()传递? 如果使用viewData参数,则我的POST参数将更改为GET参数。
解决方案是使用TempData属性存储所需的Request组件。
例如:
1 2 3 4 5
| public ActionResult Send()
{
TempData["form"] = Request.Form;
return this.RedirectToAction(a => a.Form());
} |
然后,您可以在"表单"操作中执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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);
} |
请记住,TempData在会话中存储表单集合。如果您不喜欢这种行为,则可以实现新的ITempDataProvider接口,并使用其他某种机制来存储临时数据。除非您知道一个事实(通过测量和分析),否则使用Session状态会伤害您,否则我不会这样做。
看一下MVCContrib,您可以执行以下操作:
1 2 3 4 5 6 7
| using MvcContrib.Filters;
[ModelStateToTempData]
public class MyController : Controller {
//
...
} |
还有另一种避免使用tempdata的方法。我喜欢的模式涉及为无效表单的原始渲染和重新渲染创建1个动作。它是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 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验证框架中简化此模式。
如果要将数据传递给重定向的操作,可以使用的方法是:
1 2
| return RedirectToAction("ModelUpdated", new {id = 1});
// The definition of the action method like public ActionResult ModelUpdated(int id); |