ASP.NET MVC模型验证不适用于ViewModel

Nes*_*tor 5 c# asp.net-mvc

我有一个ViewModel,它包含一个Model和一些额外的属性.模型和属性上有验证,但执行时,仅检查模型上的验证,忽略属性中的验证.

该模型:

 [MetadataType(typeof(Customer_Validation))]
 public partial class Customer
 {
 }

 public class Customer_Validation
 {
     [Required(ErrorMessage="Please enter your First Name")]
     public string FirstName { get; set; }

     [Required(ErrorMessage = "Please enter your Last name")]
     public string LastName { get; set; }

     [Required(ErrorMessage = "Sorry, e-mail cannot be empty")]
     [Email(ErrorMessage="Invalid e-mail")]
     public string Email { get; set; }
 }
Run Code Online (Sandbox Code Playgroud)

ViewModel

 public class RegisterViewModel
 {
     public Customer NewCustomer { get; private set; }

     [Required(ErrorMessage="Required")]
     public string Password { get; private set; }

     public RegisterViewModel(Customer customer, string password)
     {
         NewCustomer = customer;
         Password = password;
     }
 }
Run Code Online (Sandbox Code Playgroud)

控制器

public ActionResult Create()
{
     Customer customer = new Customer();    
     RegisterViewModel model = new RegisterViewModel(customer, "");    
     return View(model);
}

[HttpPost]
public ActionResult Create(Customer newCustomer, string password)
{
     if (ModelState.IsValid)
     {
         try
         {
             // code to save to database, redirect to other page
         }
         catch
         {
             RegisterViewModel model = new RegisterViewModel(newCustomer, password);
             return View(model);
         }
     }
     else
     {
         RegisterViewModel model = new RegisterViewModel(newCustomer, password);
         return View(model);
     }
}
Run Code Online (Sandbox Code Playgroud)

风景

@using (Html.BeginForm())
 {
  <table>
   <tr>
    <td>First Name:</td>
    <td>@Html.TextBoxFor(m => m.NewCustomer.FirstName)</td>
    <td>@Html.ValidationMessageFor(m => m.NewCustomer.FirstName)</td>
   </tr>
   <tr>
    <td>Last Name:</td>
    <td>@Html.TextBoxFor(m => m.NewCustomer.LastName)</td>
    <td>@Html.ValidationMessageFor(m => m.NewCustomer.LastName)</td>
   </tr>
   <tr>
    <td>E-mail:</td>
    <td>@Html.TextBoxFor(m => m.NewCustomer.Email)</td>
    <td>@Html.ValidationMessageFor(m => m.NewCustomer.Email)</td>
   </tr>
   <tr>
    <td>Password:</td>
    <td>@Html.TextBoxFor(m => m.Password)</td>
    <td>@Html.ValidationMessageFor(m => m.Password)</td>
   </tr>
  </table>

  <input type="submit" value="Register" />
 }
Run Code Online (Sandbox Code Playgroud)

如果我提交表格,将密码留空,请通过.如果我将客户字段留空,则会显示错误(密码字段除外)

Dar*_*rov 10

这很正常.POST控制器操作Customer作为参数而不是视图模型.验证由模型绑定器执行,因此当模型绑定器尝试从请求参数绑定Customer对象时,它将调用验证.如果要在此视图模型上执行验证,则POST操作需要将视图模型作为参数.目前你在post动作中使用这个视图模型所做的就是调用构造函数并调用构造函数根本不会触发任何验证.

所以你的POST动作应该变成:

[HttpPost]
public ActionResult Create(RegisterViewModel newCustomer)
{
     if (ModelState.IsValid)
     {
         // code to save to database, redirect to other page
     }
     else
     {
         return View(newCustomer);
     }
}
Run Code Online (Sandbox Code Playgroud)

请注意您不需要将密码作为第二个操作参数传递,因为它已经是视图模型的一部分.