ASP.Net MVC 4.0 - 验证问题ViewModel上基于数组的属性

时间:2014-02-21 11:01:05

标签: asp.net-mvc validation

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

1 个答案:

答案 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)