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

Posted

技术标签:

【中文标题】如何在 ASP.NET MVC 中 RedirectToAction 而不会丢失请求数据【英文标题】:How to RedirectToAction in ASP.NET MVC without losing request data 【发布时间】:2010-09-05 08:11:21 【问题描述】:

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

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

由于我要求表单包含最初的POSTed 数据,为了用户方便以及验证目的,我如何通过RedirectToAction() 传递数据?如果我使用viewData参数,我的POST参数会变成GET参数。

【问题讨论】:

这是一个类似的问题(关于同一主题),但与这个问题不同。无论如何,对这个问题感兴趣的人仍然可能会感兴趣:http://***.com/questions/129335/how-do-you-redirecttoaction-using-post-intead-of-get 如果出现错误,为什么不返回相同的视图?如果模型有效,通常会调用 RedirectToAction - 或者我错过了什么?! 【参考方案1】:

解决方案是使用 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);

【讨论】:

RedirectToAction(a => a.Form()) 使用 MVCv2 无法为我编译,您使用的是 MVCv3 吗? 这是 MVC1 (2008) 之前的版本。我相信 lambda 在某个阶段被删除了(有一个 codeplex 项目 MVCContrib 重新引入了它们,尽管您也可以在那个阶段使用它们的辅助属性:***.com/questions/1936/…)。在 mvc2 中,您应该可以使用 RedirectToAction("Form"),即名称为字符串,尽管我大致记得 MVC 2 或 3 引入了一个与 MVCContrib 中类似的辅助属性,如果您热衷于搜索的话。【参考方案2】:

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

【讨论】:

【参考方案3】:

还有另一种避免临时数据的方法。我喜欢的模式涉及为无效表单的原始渲染和重新渲染创建 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 validation framework 中简化这种模式。

【讨论】:

我也使用 TempData,据我所知,问题在于您的解决方案 Deeno 是,如果用户在发布无效数据后刷新页面,他们会收到“您想重新提交表格数据”确认。正如 MattMitchell 所说,使用 TempData 解决方案可以消除这个问题。 酷。似乎有人在预览版 5 中也注意到了这个基本想法。【参考方案4】:

看看MVCContrib,你可以这样做:

using MvcContrib.Filters;

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

【讨论】:

【参考方案5】:

如果你想将数据传递给重定向的动作,你可以使用的方法是:

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

【讨论】:

【参考方案6】:

TempData 是保持数据从一个动作到另一个动作的解决方案。

Employee employee = new Employee
                
                        EmpID = "121",
                        EmpFirstName = "Imran",
                        EmpLastName = "Ghani"
                ;
                TempData["Employee"] = employee;

【讨论】:

以上是关于如何在 ASP.NET MVC 中 RedirectToAction 而不会丢失请求数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 asp.net-mvc 控制器中集中授权逻辑?

asp.net mvc 如何添加css

如何在 ASP.NET 5 MVC 6 (vNext) 中定义 Identity 的密码规则?

如何在 ASP.NET Core 5 MVC (.NET 5) 中获取记录的用户数据?

如何在 Asp.Net mvc 5 的 grid.mvc 中添加两个按钮

如何在 Asp.Net 5 (MVC 6) 中使用实体框架 6.x