我想在MVC用户表单中输入数据并将其显示在不同的视图中。
该类具有以下私有变量:
IList<string> _pagecontent = new List<string>();
以下操作接受FormCollection对象,对其进行验证,并将其作为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);
}
预览视图具有以下页面指令,用于传递强类型对象列表:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Template.Master" Inherits="System.Web.Mvc.ViewPage<List<string>>" %>
我希望能够使用Model对象来获取我的数据,但是我不能。在接下来的行中,我得到一个error index out of bounds
异常,声明索引必须是非负数且小于集合的大小:
<% if (Model[0].ToString() == "0") { %>
一些奇怪的参数已经添加到URL中,因为它解析为
http://localhost:1894/Admin/Preview?Capacity=4&Count=3
所以我有两个问题:
答案 0 :(得分:55)
尝试使用TempData。它就像一个单次会话对象。您将所需的值放入TempData,立即重定向并将其取出。这里有一篇很好的文章:http://blogs.teamb.com/craigstuntz/2009/01/23/37947/
答案 1 :(得分:11)
使用TempData时要小心。它在单个服务器环境中运行良好,但在云环境中,它可能无法按预期工作,因为您无法保证请求将在同一台计算机上运行。这是因为TempData依赖于asp.net会话。但是如果您使用其他会话管理器(如SQL或AppFabric Cache),它将正常工作。
答案 2 :(得分:7)
RedirectAction的第二个参数是routeValues,而不是model。
protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues);
尝试将TempData用于模型。它用于在重定向之间保持数据。
答案 3 :(得分:4)
RedirectToAction的问题在于它返回了一个HTTP 302,然后浏览器自行开始并执行一个全新的HTTP请求。您可能需要考虑使用cookie和/或会话对象在请求之间保留数据。
答案 4 :(得分:3)
这不起作用,因为RedirectToAction实际上是将Http 302发送回浏览器。当浏览器接收到该302时,它向服务器发出新请求以请求新页面。新请求,新临时变量。
当您尝试保存/编辑/删除某些内容时,您也会遇到此问题,并且由于某种原因您拒绝它并且您必须再次返回旧表单。
所以,而不是:
return RedirectToAction("Preview", _pagecontent);
将预览逻辑放在一个单独的方法中,然后调用它:
return PreviewLogic(_pagecontent);
你也可以像其他人所说的那样使用TempData [] dic来保存下一个请求的数据,但是你不会避免额外往返服务器的302次。
答案 5 :(得分:2)
听起来你正试图这样做:
public ActionResult UpdateContent(FormCollection form) {
...
return View("Preview", _pagecontent);
}
请注意,重定向应该是浏览器的“清单”(除了auth cookie之类的东西)。您无法告诉浏览器将信息传递给下一个请求,因为下一个请求应该能够独立存在。您要做的就是告诉浏览器接下来要请求的URL。在ASP.NET MVC中,当您将arguments-object传递给RedirectToAction
时,该对象的公共属性将作为查询字符串参数附加到生成的URL中。
答案 6 :(得分:0)
你不能只用同一个名字制作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);
}
答案 7 :(得分:-3)