2012-11-06 41 views
4

我是MVC Razor的新手,我想在文本框上实现验证消息。在这里,我动态创建文本框的一些如下:如何在mvc4剃须刀显示验证消息

查看代码:

foreach (var items in (IEnumerable<System.Data.DataRow>)Model.UsersOfList) 
{ 

    @Html.TextBoxFor(m => m.LoginNameOfLoginInfoTab, new { @class = "textBox_LoginInfoAndPermission", @value = (Model.LoginNameOfLoginInfoTab = items["UserName"].ToString()), @id = ("txtUserLoginName" + Model.UsernameOfLoginInfoTab.Trim()) }) 

    @Html.ValidationMessageFor(m => m.LoginNameOfLoginInfoTab, null, new { @class = "ErrorMessage" }) 

    @Html.TextBoxFor(m => m.UsernameOfLoginInfoTab, new { @class = "textBox_LoginInfoAndPermission", @value = (Model.UsernameOfLoginInfoTab = items["FirstName"].ToString()), @id = ("txtUserName" + Model.UsernameOfLoginInfoTab.Trim()) }) 

    @Html.ValidationMessageFor(m => m.UsernameOfLoginInfoTab, null, new { @class = "ErrorMessage" }) 


} 

模块中我写的代码进行验证如下:

[Required (ErrorMessage="*")] 
    public string UsernameOfLoginInfoTab 
    { 
     get; 
     set; 
    } 


    [Required(ErrorMessage = "*")] 
    public string LoginNameOfLoginInfoTab 
    { 
     get; 
     set; 
    } 

现在,当所有文本框已创建,并且当第一个循环迭代文本框显示一条验证消息时,它将自动显示在另一个文本框的前面,该文本框在第二个循环迭代中创建。

请告诉我什么是错的。

回答

9

问题是因为您使用的是TextBoxForValidationMessageFor它使用MVC为场创建一个字符串名称,并从ModelState查找验证消息的表情,始终是整个循环的迭代相同。

你的方法在这里似乎有点缺陷,所以我的答案更全面。

1)制作结构上代表您试图显示的信息的视图模型。

解决您的视图模型:

public class UserInfoViewModel 
{ 
    [Required (ErrorMessage="*")] 
    public string UserName { get; set; } 


    [Required(ErrorMessage = "*")] 
    public string LoginName { get; set; } 
} 

// I don't know if you actually need this or not, but your existing model may contain additional properties relevant to the view that I don't know about, so I'll keep it. 
public class ListOfUsersViewModel 
{ 
    public IList<UserInfoViewModel> UsersOfList { get; set; } 
} 

修正你的动作(我在做这件事在这里想说明一个观点):

public ActionResult ListOfUsers() 
{ 
    var users = GetUserDataRows(); // gets your collection of DataRows 
    var model = new ListOfUsersViewModel 
        { 
         UsersOfList = users.Select(row = new UserViewModel { UserName = row["FirstName"], LoginName = row["UserName"] }).ToList() 
        }; 

    return View(model);     
} 

2)现在,你可以通过在用户的迭代使用验证消息查看并创建适当的字段。

我们称之为ListOfUsers.cshtml。在视图中包含所需的任何其他内容,但改为使用for循环。

@using(Html.BeginForm("ListOfUsers")) 
{ 
    <ul> 
    @for (var i = 0; i < Model.UsersOfList.Count; i++) 
    { 
     <li> 
     @Html.TextBoxFor(m.UsersOfList[i].LoginName, new {@class="textbox_LoginInfoAndPermission"}) 
     @Html.ValidationMessageFor(m => m.UsersOfList[i].LoginName) 

     @Html.TextBoxFor(m.UsersOfList[i].UserName, new {@class="textbox_LoginInfoAndPermission"}) 
     @Html.ValidationMessageFor(m => m.UsersOfList[i].UserName) 
     </li> 
    } 
    </ul> 
    <button type="submit">Submit changes</button> 
} 

这将导致HTML这样每个项目(在名称0和id将是用户的集合中的指标):

<li> 
<input type="text" id="UsersOfList_0_LoginName" name="UsersOfList[0].LoginName" value="..." /> 
<span class="field-validation-valid" data-valmsg-for="UsersOfList_0_LoginName" ... ></span> 

<input type="text" id="UsersOfList_0_UserName" name="UsersOfList[0].UserName" value="..." /> 
<span class="field-validation-valid" data-valmsg-for="UsersOfList_0_UserName" ... ></span> 
</li> 

3)创建一个动作来接收提交的更改。此操作将自动将提交的值绑定到model参数,并为您进行验证。所有你需要做的是检查ModelState.IsValid

[HttpPost, ActionName("ListOfUsers")] 
public ActionResult ListOfUsersPost(ListOfUsersViewModel model) 
{ 
    // at this point, model will be instantiated, complete with UsersOfList with values submitted by the user 

    if (ModelState.IsValid) // check to see if any users are missing required fields. if not... 
    { 
     // save the submitted changes, then redirect to a success page or whatever, like I do below 
     return RedirectToAction("UsersUpdated"); 
    } 

    // if ModelState.IsValid is false, a required field or other validation failed. Just return the model and reuse the ListOfUsers view. Doing this will keep the values the user submitted, but also include the validation error messages so they can correct their errors and try submitting again 
    return View("ListOfUsers", model); 

} 
+0

您可以在视图中使用foreach循环而不是for循环。这将消除每次访问用户时索引的需求(即,您将拥有user.UserName而不是m.UsersOfList [i] .UserName)。 – rouan

+3

@rouan你需要在那里的索引器,所以MVC的'TextBoxFor'和'ValidationMessageFor'助手将分别为模型绑定和模型状态的键生成正确的HTML元素ID /名称。 – HackedByChinese