我很难清楚地说明我遇到的问题。我试图了解如何在验证失败后保留在循环中创建的表单字段中的值。我有一个更复杂的真实世界形式,在循环和验证中创建了一堆元素。我把它简化为一个简单的例子
当验证失败时,我希望在循环中创建的名为“Comment”的textareas保留下面提交前图像中显示的值。
当我调试表单提交时,每个字段的值都成功连接到模型中名为Comment的IList变量。这就是我想要的,所以我可以循环并根据索引找到它们
提交后,循环生成的每个textarea显示模型中IList变量Comment的逗号分隔表示。看来视图和模型中的字段是连接的,因为它们共享一个名称。它们在途中正确连接但不在出路上。我希望视图只显示与Comment [i]相关的值而不是整个列表,以便在表单提交之间保持值不变。
屏幕截图和下面的示例代码
首次加载:
预先提交表单更改:
首次提交后看到的表格:
第二次提交后看到的表格:
型号代码
using System.Collections.Generic;
namespace UI.Models.Forms
{
public class TempListModel : ContentModel
{
public TempListModel()
{
Comment = new List<string>();
}
public IList<string> Comment { get; set; } //Comments for each URL in the list
}
}
查看代码
@model UI.Models.Forms.TempListModel
@using (Html.BeginForm("temptest", "Test", new { id = 1 }, FormMethod.Post, new { id = "listForm", name = "listForm" }))
{
<ul>
@for (int i = 0; i < Model.Comment.Count(); i++)
{
<li>
<div class="llformlabel">
Notes:
<div>@Model.Comment[i]</div>
@Html.TextArea("Comment", Model.Comment[i], 4, 63, new { @id = "Comment_" + i, @title = "Comment" })</div>
</li>
}
</ul>
<input type="submit" value="Save Changes" />
}
控制器代码
using System.Collections.Generic;
using System.Web.Mvc;
using UI.Models.Forms;
namespace UI.Controllers
{
public class TestController : Controller
{
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult TempTest(TempListModel model)
{
//This function executes after the user submits the form.
//If server side validation fails then the user should be shown the form as it was when they submitted.
//model.Comment = GetComments(); //In my real world example this comes from a database.
if (true) //!ModelState.IsValid) //In my real world code this is a validation step that may fail
{
return View(model);
}
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult TempTest(int? id)
{
//In the real world example there is a lot going on in this function.
//It is used to load data from databases and set up the model to be displayed.
var model = new TempListModel();
model.Comment = GetComments();
return View("TempTest", "TempLayout", model);
}
private static IList<string> GetComments()
{
//Simple sample function used for demo purposes.
IList<string> comments = new List<string>();
comments.Add("Comment 1");
comments.Add("Comment 2");
comments.Add("Comment 3");
return comments;
}
}
}
答案 0 :(得分:8)
如果验证失败,只需返回模型。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult TempTest(TempListModel model)
{
if (ModelState.IsValid)
{
return RedirectToAction("TempTest");
}
return View(model);
}
修改在您的视图中尝试此操作
@for (int i = 0; i < Model.Comment.Count(); i++)
{
<li>
@Html.TextAreaFor(m => m.Comment[i], 4, 63, new { @title = "Comment" })
</li>
}
让助手为你命名元素。您最终会得到name
等Comment[i]
属性。
答案 1 :(得分:2)
ASP.NET MVC默认的ModelBinder在请求中查找与TempListModel属性匹配的HTML名称,以便在服务器中构建模型。但是你要覆盖每个HTML元素的注释ID:
的
的@Html.TextArea("Comment", Model.Comment[i], 4, 63, new { @id = "Comment_" + i, @title = "Comment" })
的
如果您需要放置此自定义ID,则必须创建新的ModelBinder。 你可以像这样保持简单:
的
的 @Html.TextAreaFor(m => m.Comment[i], 4, 63, new { @title = "Comment" })
的
希望对你有所帮助!