2011-01-31 89 views
8

这是一个控制器的动作,我用AJAX POST方法调用:如何更新ModelState?

[HttpPost] 
    public ActionResult Add(Comment comment) 
    { 
     if (User.Identity.IsAuthenticated) 
     { 
      comment.Username = User.Identity.Name; 
      comment.Email = Membership.GetUser().Email; 
     } 

     if (ModelState.IsValid) 
     { 
      this.db.Add(comment); 
      return PartialView("Comment", comment); 
     } 
     else 
     { 
      //... 
     } 
    } 

如果用户登录,提交表单没有用户名和电子邮件领域,所以他们没有得到通过AJAX调用传递。当操作被调用时,ModelStat.IsValid返回false,因为这两个属性是必需的。将有效值设置为属性后,如何触发模型验证以更新ModelState?

回答

4

您可以使用自定义model binder从User.Identity绑定评论的用户名和电子邮件属性。因为绑定发生在验证之前,所以ModelState将是有效的。

另一种选择是为Comment类实现自定义model validator,该类将检查ControllerContext.Controller是否为经过验证的用户。

通过实施这些选项中的任何一个,您可以删除第一个选项。

3

您可以尝试调用内置的TryUpdateModel方法,该方法返回一个布尔值,以便您可以检查该值。

更新:尝试使用带有例外的TryUpdateModel。在行动中使用表单集合而不是评论。

[HttpPost] 
    public ActionResult Add(FormCollection collection) 
    { 

     string[] excludedProperties = new string[] { "Username". "Email" }; 
     var comment = new Comment(); 
     if (User.Identity.IsAuthenticated) 
     { 
      comment.Username = User.Identity.Name; 
      comment.Email = Membership.GetUser().Email; 
     } 

     TryUpdateModel<Comment>(comment, "", null, excludedProperties, collection.ToValueProvider()); 

     if (ModelState.IsValid) 
     { 
      this.db.Add(comment); 
      return PartialView("Comment", comment); 
     } 
     else 
     { 
      //... 
     } 
    } 
+0

不,这是我第一次尝试和控制器中的所有其他方法:UpdateModel,ValidateModel,TryValidate。没有任何工作,我得到一个例外:模型不能更新/验证或类似的东西。 – frennky 2011-02-01 06:46:29

+0

在这种情况下,为什么不使用ViewModel?这将包含您传递给Action的所有属性,无需担心丢失的内容。 – Jon 2011-02-01 09:38:15