MVC – 使用RedirectToAction()传递数据

我想将数据input到MVC用户表单中,并以不同的视图显示。

该类有以下私有variables:

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

以下操作接受一个FormCollection对象,对其进行validation,并将其作为List传递给“Preview”视图:

 [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); } 

预览视图具有以下页面指令来传递强types对象列表:

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

我希望能够使用模型对象来获取我的数据,但唉,我不能。 在下面一行中,我得到一个error index out of boundsexception,说明索引必须是非负数,小于集合的大小:

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

还有一些奇怪的参数已经被添加到URL中,因为它parsing为http://localhost:1894/Admin/Preview?Capacity=4&Count=3

所以我有两个问题:

  1. 当我调用RedirectToAction并将其传递给List时,为什么在视图的Model对象中不可访问?
  2. 什么是正确的方式去做我想做的事情,即传递一个string集合到一个视图在那里显示?

尝试使用TempData。 这就像一个单一的会话对象。 你把你想要的值放入TempData,立即redirect并把它们取出。 这里有一个很好的写法: http : //blogs.teamb.com/craigstuntz/2009/01/23/37947/

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

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

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

尝试使用TempData模型。 它用于在redirect之间保存数据。

RedirectToAction的问题是它返回一个HTTP 302,然后浏览器自己去做一个全新的HTTP请求。 您可能要考虑使用cookie和/或会话对象来在请求之间保持数据。

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

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

所以,而不是:

 return RedirectToAction("Preview", _pagecontent); 

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

 return PreviewLogic(_pagecontent); 

您也可以像使用其他人所说的那样,使用TempData [] dic来保存下一个请求的数据,但是您不会避免额外往返于服务器。

这听起来像你试图做的:

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

请注意,redirect应该是浏览器的“干净页面”(除了auth cookie以外)。 您不必告诉浏览器将信息传递给下一个请求,因为下一个请求应该能够独立运行。 你所要做的就是告诉浏览器接下来要请求的URL。 在ASP.NET MVC中,将参数对象传递给RedirectToAction ,该对象的公共属性作为查询string参数附加到生成的URL。

难道你不能只使用相同的名称做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方法