【问题标题】:check Model State of a property检查属性的模型状态
【发布时间】:2014-01-21 15:59:14
【问题描述】:

我的礼物控制器有一个动作结果,它在参数中使用一个 GiftViewModel 来检查模型状态。

我刚刚向 GiftViewModel 添加了一个 LoginModel 属性。我想测试这个属性的modelState。

GiftViewModel.cs:

    public class GiftViewModel
{

    public LoginModel login { get; set; }
    [...]

}

GiftController.cs

//
    // POST: /Gift/Login
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Login(GiftViewModel model, string returnUrl)
    {
        // here instead of the overall modelstate
        // I would like to check only the modestate of the login property 
        // of my model
        if (ModelState.IsValid && WebSecurity.Login(model.login.Email, model.login.Password, persistCookie: model.login.RememberMe))
        {
            return View("Index", model);
        }

        return View("Index", model);
    }

我该如何管理它?

【问题讨论】:

  • 你为什么需要那个?您会允许主视图模型的其他属性使用无效值吗?
  • 是的,没错,我只想先验证这个“步骤”。
  • 没有办法做到这一点。立即验证整个模型。

标签: c# asp.net-mvc-4


【解决方案1】:

如果您只想检查属性的有效性,那么如何使用:

var propertyToValidate = ModelState["PropertyName"];
if(propertyToValidate==null || //exclude if this could not happen or not to be counted as error
    (propertyToValidate!=null && propertyToValidate.Errors.Any())
   )
{
    //Do what you want if this value is not valid
}
 //Rest of code

但请注意,在这种情况下,模型的其余部分已经过验证。您只是在检查 ModelState 的其余部分之前检查此属性的有效性。如果您想先进行实际验证,则必须在 GiftViewModel 的自定义 ModelBinder 中实现。

【讨论】:

    【解决方案2】:

    我做了一个模型状态扩展,让它变得非常简单:

    public static class ModelStateDictionaryExtensions
    {
    
        /// <summary>
        /// Returns true when a model state validation error is found for the property provided
        /// </summary>
        /// <typeparam name="TModel">Model type to search</typeparam>
        /// <typeparam name="TProp">Property type searching</typeparam>
        /// <param name="expression">Property to search for</param>
        /// <returns></returns>
        public static bool HasErrorForProperty<TModel, TProp>(this System.Web.Mvc.ModelStateDictionary modelState,
                                        Expression<Func<TModel, TProp>> expression)
        {
            var memberExpression = expression.Body as MemberExpression;
    
            for (int i = 0; i < modelState.Keys.Count; i++)
            {
                if (modelState.Keys.ElementAt(i).Equals(memberExpression.Member.Name))
                {
    
                    return modelState.Values.ElementAt(i).Errors.Count > 0;
    
                }
            }
    
            return false;
        }
    }
    

    使用上述方法,您只需输入:

    if (ModelState.HasErrorForProperty<GiftViewModel, LoginModel >(e => e.login))
    

    【讨论】:

      【解决方案3】:

      这样的事情怎么样?

       public class GiftViewModel
      {
      
         public class LoginModel
         {
              [Required(ErrorMessage = "Email Required")]
              RegularExpression(".+\\@.+\\..+", ErrorMessage = "You must type in a valid email address.")]
              public string Email { get; set; }
      
              [Required(ErrorMessage = "Password Required")]
              public string password { get; set; }
         }
      
      }
      
      
       public ActionResult Login(GiftViewModel model)
       {
            if(TryValidateModel(model))
            {
               ///validated with all validations
             }
      
          return View("Index", model);
      }
      

      【讨论】:

      • 不是真的,因为 GiftViewModel 可能有其他无效的属性。我只想检查 LoginModel 属性的有效性。
      • 明白了。您是否有理由在服务器上执行此操作而不是使用客户端验证?如果您确实想在服务器上执行此操作,您的 LoginModel 可以使用方法 Validate 实现 IValidatableObject,您可以在其中放置您的验证代码。
      • 我刚刚选择了“TryValidateModel(model)”,它对我有用。希望它也可以为您工作 var result = _uow.User.GetUserContactInformationUserProfileId(userProfileId); if (TryValidateModel(result)) { ViewBag.Sample = "Sample"; }
      【解决方案4】:

      第一个也是最简单的解决方案是在将结果返回到服务器之前在验证(客户端)中添加代码。

      Simplest JQuery validation rules example

      第二个也是更复杂的方法是为登录创建自定义验证属性

      【讨论】:

        猜你喜欢
        • 2012-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多