ASP.Net MVC 4.0 - 验证问题ViewModel上基于数组的属性。
场景: 当ViewModel将字符串数组作为属性类型时,默认的Scaffolding模板(例如Edit)不会在标记中呈现该属性。
说,我有这样的ViewModel设置:
Employee.cs
public class Employee
{
[Required]
public int EmpID
{
get;
set;
}
[Required]
public string FirstName
{
get;
set;
}
[Required]
public string LastName
{
get;
set;
}
[Required]
public string[] Skills
{
get;
set;
}
}
}
脚手架模板生成的(强类型)编辑视图,如下所示,通常会跳过与字段技能相关的部分。
**Employee.cshtml**
@model StringArray.Models.Employee
@{
ViewBag.Title = "EditEmployee";
}
<h2>EditEmployee</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Employee</legend>
<div class="editor-label">
@Html.LabelFor(model => model.EmpID)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.EmpID)
@Html.ValidationMessageFor(model => model.EmpID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.FirstName)
@Html.ValidationMessageFor(model => model.FirstName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.LastName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.LastName)
@Html.ValidationMessageFor(model => model.LastName)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
相应的Controller代码是
..
[HttpGet]
public ActionResult EditEmployee()
{
Employee E = new Employee()
{
EmpID = 1,
FirstName = "Sandy",
LastName = "Peterson",
Skills = new string[] { "Technology", "Management", "Sports" }
};
return View(E);
}
[HttpPost]
public ActionResult EditEmployee(Employee E)
{
return View(E);
}
要获取技能字段的缺失部分,我添加了
视图片段
<div class="editor-label">
@Html.LabelFor(model => model.Skills)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Skills)
@Html.ValidationMessageFor(model => model.Skills)
</div>
对应于ViewModel的UIHint
[UIHint( “字符串[]”)] public string []技能......
EditorTemplates在相关文件夹中 〜\视图\共享\ EditorTemplates \字符串[]。CSHTML 和 〜\查看共享\ \ EditorTemplates \ mystring.cshtml
string []。cshtml
@model System.String[]
@if(Model != null && Model.Any())
{
for (int i = 0; i < Model.Length; i++)
{
@Html.EditorFor(model => model[i], "mystring")
//Html.ValidationMessageFor(model => model[i])
}
}
mystring.cshtml
@model System.String
@{
//if(Model != null)
{
//To resolve issue/bug with extra dot getting rendered in the name - like
//Skills.[0], Skills.[1], etc.
//ViewData.TemplateInfo.HtmlFieldPrefix=ViewData.TemplateInfo.HtmlFieldPrefix.Replace(".[", "[");
@Html.TextBoxFor(model => model)
}
}
但尽管如此,技能部分的验证[包含3个字段/元素 - 请参阅上面的Controller中的EditEmployee方法。] 在回发时完全被跳过。
我在mystring.cshtml EditorTemplate中尝试了以下更改:
//to correct the rendered names in the browser from Skills.[0] to Skills for all the 3 items in the
//Skills (string array), so that model binding works correctly.
string x = ViewData.TemplateInfo.HtmlFieldPrefix;
x = x.Substring(0, x.LastIndexOf("."));
@Html.TextBoxFor(model =>model, new { Name = x })
回发作品但是验证没有,因为“ data-valmsg-for ”仍然指向 <span class="field-validation-valid" data-valmsg-for="Skills" data-valmsg-replace="true"></span>
因此不适用于粒度级别 - 字符串元素级别。
最后,我尝试从Employee.cshtml中删除@ Html.ValidationMessageFor(model =&gt; model.Skills)并相应地添加 与字符串[] .cshtml相同,为@ Html.ValidationMessageFor(model =&gt; model [i])。 但这导致data-valmsg-为每个粒状字符串元素(如
)进行渲染data-valmsg-for =“技能。[0]”, data-valmsg-for =“Skills。[1]”和data-valmsg-for =“Skills。[2]”。
注意:验证适用于其他字段 - EmpID,FirstName LastName,但不适用于技能。
问题 如何为与技能属性相关的上述三个粒度元素中的每一个设置data-valmsg-for =“Skills”。
我现在已经坚持了很长一段时间。如果有人能够最早指出这个问题,那就太好了。
谢谢,Sandesh L
答案 0 :(得分:1)
这是您想要更改的地方
[Required]
public string[] Skills
{
get;
set;
}
您正在对阵列进行验证。
你可能想要一个新的字符串类调用Skill
[Required]
public string Skill
{
get;
set;
}
你可以用
改变你的模特 [Required]
public List<Skill> Skills
{
get;
set;
}
我更喜欢使用List而不是数组。然后,您可以根据更新的模型更改技能视图
你的模板视图可以是
@model IEnumerable<Skill>
<div class="editor-label">
<h3>@Html.LabelFor(model=> model.Skills)
</h3>
</div>
<div class="editor-field">
@foreach (var item in Model)
{ @Html.Label(model => item)
@Html.TextBoxFor(model => item) <br/>
}
@Html.ValidationMessageFor(model => item)