繁体   English   中英

MVC - 使用 RedirectToAction() 传递数据

[英]MVC - Passing Data with RedirectToAction()

我想获取在 MVC 用户表单中输入的数据并将其显示在不同的视图中。

class 具有以下私有变量:

IList<string> _pagecontent = new List<string>();

以下操作接受 FormCollection object,对其进行验证,并将其作为列表传递给“预览”视图:

[Authorize(Roles = "Admins")]
[ValidateInput(false)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UpdateContent(FormCollection collection)
{
    if (ModelState.IsValid)
    {
        string PageToInsert = collection["PageToInsert"];
        string PageHeader = collection["PageHeader"];
        string PageBody = collection["PageBody"];

        //validate, excluded...

        _pagecontent.Add(PageToInsert);
        _pagecontent.Add(PageHeader);
        _pagecontent.Add(PageBody);

    }
    return RedirectToAction("Preview", _pagecontent);
}

预览视图具有以下用于传递强类型 object 列表的页面指令:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Template.Master" Inherits="System.Web.Mvc.ViewPage<List<string>>" %>

我希望能够使用 Model object 来获取我的数据,但可惜我不能。 在下一行,我得到一个error index out of bounds异常,指出索引必须是非负数并且小于集合的大小:

<% if (Model[0].ToString() == "0") { %>

URL 中添加了一些奇怪的参数,因为它解析为http://localhost:1894/Admin/Preview?Capacity=4&Count=3

所以我有两个问题:

  1. 当我调用 RedirectToAction 并将它传递给我的列表时,为什么它在视图的 Model object 中无法访问?
  2. go 关于做我想做的事情的正确方法是什么,即将字符串集合传递给视图以在那里显示?

尝试使用 TempData。 它就像一个单发 session object。 您将所需的值放入 TempData,立即重定向并将它们取出。 这里有一篇很好的文章: http://blogs.teamb.com/craigstuntz/2009/01/23/37947/

使用 TempData 时要小心。 它在单个服务器环境中运行良好,但在云环境中它可能无法按预期运行,因为您不能保证请求会到达同一台机器。 发生这种情况是因为 TempData 依赖于 asp.net session。 但是,如果您使用其他 session 管理器,例如 SQL 或 AppFabric Cache,它将正常工作。

RedirectAction 的第二个参数是 routeValues,而不是 model。

protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues);

尝试对 model 使用 TempData。 它用于在重定向之间保留数据。

RedirectToAction 的问题在于它返回了 HTTP 302 ,然后浏览器自行运行并执行全新的 HTTP 请求。 您可能需要考虑使用 cookie 和/或 session object 在请求之间保留数据。

这不起作用,因为 RedirectToAction 实际上是将 Http 302 发送回浏览器。 当浏览器收到这个 302 时,它会向服务器发出一个新请求,请求新页面。 新请求,新临时变量。

当您尝试保存/编辑/删除某些内容并且由于某种原因您拒绝它并且您必须再次返回旧表单时,您也会遇到这个问题。

所以,而不是:

return RedirectToAction("Preview", _pagecontent);

将预览逻辑放在一个单独的方法中,然后调用它:

return PreviewLogic(_pagecontent);

您还可以像其他人所说的那样使用 TempData[] dic 为下一个请求保留数据,但是您将无法避免到服务器的 302 额外往返。

听起来您正在尝试这样做:

public ActionResult UpdateContent(FormCollection form) {
    ...
    return View("Preview", _pagecontent);
}

请注意,重定向应该是浏览器的“干净的石板”(除了 auth cookie 之类的东西)。 您不必告诉浏览器将信息传递给下一个请求,因为下一个请求应该能够独立存在。 你要做的就是告诉浏览器接下来要请求什么 URL 。 在 ASP.NET MVC 中,当您将 arguments-object 传递给RedirectToAction时,该 object 的公共属性将作为查询字符串参数附加到生成的 ZE6B391A8D2C4D45902A23A8B658DZZ03。

您不能只制作 2 个具有相同名称的操作结果并用 HttpPost 标记其中的 1 个吗?

    public ActionResult UpdateContent(FormCollection preview = null)
    {
        return View(preview);
    }
    [HttpPost]
    public ActionResult UpdateContent(FormCollection collection = null, bool preview = false)
    {
        if (preview)
            return UpdateContent(collection);
        else
            return UpdateContent(null);
    }

看起来您正在寻找 UpdateModel 命令:

查看 ScottGu 关于该主题的博客文章:

改进的 UpdateModel 和 TryUpdateModel 方法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM