3

I have my Gift Controller with an action result which takes a GiftViewModel in argument tu check the model state.

I just added a LoginModel property to GiftViewModel. And I would like to test the modelState of just this property.

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);
    }

How can I manage it ?

Cactus
  • 175
  • 2
  • 12

4 Answers4

7

If all you want to do is the to check the validity of a property, how about using:

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

But do note that in this case the rest of the model has already been validated. You are just checking the validity of this property before checking the rest of the ModelState. If you want to do the actual validation first, then this would have to be implemented in a custom ModelBinder for the GiftViewModel.

JTMon
  • 3,189
  • 22
  • 24
5

I made a model state extension, which makes it really easy:

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;
    }
}

Using the method above, you would simply enter:

if (ModelState.HasErrorForProperty<GiftViewModel, LoginModel >(e => e.login))
Ian
  • 2,898
  • 1
  • 27
  • 29
2

How about something like this?

 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);
}
m0r6aN
  • 850
  • 1
  • 11
  • 19
  • Hum not really, because GiftViewModel may have others properties which are not valid. I just want to check the validity of the LoginModel property. – Cactus Jan 21 '14 at 16:35
  • Gotcha. Is there a reason you're doing it on the server instead of using client side validation? If you definitely want to do it on the server, your LoginModel could implement IValidatableObject with method Validate, where you can put your validation code. – m0r6aN Jan 21 '14 at 16:59
  • I just picked "TryValidateModel(model)" and it worked for me. Hope it can work for you as well var result = _uow.User.GetUserContactInformationUserProfileId(userProfileId); if (TryValidateModel(result)) { ViewBag.Sample = "Sample"; } – sami ullah May 18 '20 at 08:40
0

The first and easiest solution is to add code in the validate (client side) before the results are returned to the server.

Simplest JQuery validation rules example

Second and more complex would be to create a custom validation attribute for login

Community
  • 1
  • 1
Mike Beeler
  • 4,081
  • 2
  • 29
  • 44