C# MVC Razor 视图中的 HTML.Textarea 值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16575560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HTML.Textarea Values in MVC Razor View
提问by RacerNerd
It is hard for me to clearly state the problem I am having. I am trying to understand how to retain values in form fields created in a loop after validation fails. I have a more complicated real world form that has a bunch of elements created in the loop and validation. I have reduced it to a simple example included below.
When validation fails I would like the textareas named "Comment" that have been created in the loop to retain the values that are shown in the Pre-Submit image below.
When I debug the form submission, the values from each of the fields are successfully connected to the IList variable named Comment found in the Model. This is what I want so I can loop through and locate them based on index.
After submitting, each textarea produced by the loop shows the comma separated representation of the IList variable Comment in the Model. It appears that the field in the view and in the model are connecting because they share a name. They connect properly on the way in but not on the way out. I would like the view to only show the value associated with the Comment[i] instead of the entire list so that the values remain constant between form submissions.
Screenshots and Sample Code Below
First Load:
Pre-Submit Form Changes:
Form as seen after first submit:
Form as seen after second submit:
Model Code
我很难清楚地说明我遇到的问题。我试图了解如何在验证失败后在循环中创建的表单字段中保留值。我有一个更复杂的现实世界表单,它在循环和验证中创建了一堆元素。我已将其简化为下面包含的一个简单示例。
当验证失败时,我希望在循环中创建的名为“Comment”的文本区域保留下面预提交图像中显示的值。
当我调试表单提交时,每个字段的值都成功连接到模型中名为 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
}
}
View Code
查看代码
@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" />
}
Controller Code
控制器代码
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;
}
}
}
采纳答案by Jasen
If you fail validation just return the model.
如果验证失败,只需返回模型。
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult TempTest(TempListModel model)
{
if (ModelState.IsValid)
{
return RedirectToAction("TempTest");
}
return View(model);
}
EditTry this in your view instead
编辑在您的视图中尝试此操作
@for (int i = 0; i < Model.Comment.Count(); i++)
{
<li>
@Html.TextAreaFor(m => m.Comment[i], 4, 63, new { @title = "Comment" })
</li>
}
And let the helper name the elements for you. You end up with nameattributes like Comment[i].
让助手为您命名元素。你最终得到name像Comment[i].
回答by Fals
ASP.NET MVC default ModelBinder looks for HTML names in the request that match TempListModel properties to build the model back in the server. But you are overriding the comment Id of each HTML Element:
ASP.NET MVC 默认 ModelBinder 在请求中查找与 TempListModel 属性匹配的 HTML 名称,以在服务器中重新构建模型。但是您要覆盖每个 HTML 元素的注释 ID:
@Html.TextArea("Comment", Model.Comment[i], 4, 63, new { @id = "Comment_" + i, @title = "Comment" })
@Html.TextArea("Comment", Model.Comment[i], 4, 63, new { @id = "Comment_" + i, @title = "Comment" })
If you need to place this custom ID, you must create a new ModelBinder. You can keep things easy like this:
如果您需要放置此自定义 ID,则必须创建一个新的ModelBinder。你可以像这样让事情变得简单:
@Html.TextAreaFor(m => m.Comment[i], 4, 63, new { @title = "Comment" })
@Html.TextAreaFor(m => m.Comment[i], 4, 63, new { @title = "Comment" })
Hopes Its help you!
希望对你有帮助!

