4

I have an ApiController, in which I have a Post method that accepts a VariableTemplateViewModel, which looks like this:

public class VariableTemplateViewModel
{
    public VariableTemplateViewModel() { }

    public double Version { get; set; }

    [Required]
    public List<VariableViewModel> Variables { get; set; }
}

public class VariableViewModel
{
    public VariableViewModel() { }

    [Required(AllowEmptyStrings=false, ErrorMessage="Variable Name cannot be empty")]
    public string Name { get; set; }
}

Inside the Post method, I do a validation check, like so:

public void Post(long id, [FromBody]VariableTemplateViewModel model)
{
    if (!ModelState.IsValid )
    {
        throw new HttpResponseException(HttpStatusCode.BadRequest);
    }   
}

This works great and if I call it with a view model that has empty Name fields in the Variables list, it fails validation. However, when I try to validate this from the Unit Test, it only runs validations on VariableViewModel itself and not recursively the VariableViewModel. So, if I pass in null for the Variables, I get a validation error but if I pass in an empty string for Name, there are no validation errors.

[TestMethod]
public void Post_Returns_HttpResponseException_With_Empty_Variable_Name()
{
    var controller = new VariableController();
    var viewModel = new VariableTemplateViewModel
                    {
                        Version = 1,
                        Variables = new List<VariableViewModel> 
                        { 
                            new VariableViewModel { Name = "" }
                        }
                    };

    var validationContext = new ValidationContext(viewModel, null, null);

    var validationResults = new List<ValidationResult>();
    Validator.TryValidateObject(viewModel, validationContext, validationResults, true);
    foreach (var validationResult in validationResults)
    {
        controller.ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage);
    }

    // Assert

}

I have tried removing/adding empty constructors and initializing Variables inside the VariableTemplateViewModel constructor. I have even tried using Validator.TryValidateObject on viewModel.Variables directly to no avail.

Does anyone know how this can be fixed?

Community
  • 1
  • 1
reggaemahn
  • 6,272
  • 6
  • 34
  • 59
  • I ended up using https://github.com/reustmd/DataAnnotationsValidatorRecursive which does precisely what I was looking for. – reggaemahn Aug 24 '16 at 07:17

1 Answers1

-1

I have a same problem and use this for the solution. May this help You.

public void Post(long id, [FromBody]VariableTemplateViewModel model)
{
    if (!ModelState.IsValid && TryValidateModel(model.NestedModel, "NestedModel."))
    {
        throw new HttpResponseException(HttpStatusCode.BadRequest);
    }   
}

Try this, Recursive Validation Using DataAnnotations

Smit Patel
  • 2,992
  • 1
  • 26
  • 44
  • 1
    Hey, thanks for the answer. However, in my case, the validation works fine in the `Post` method. It's the unit tests that are the problem. Since you can't invoke validation directly from unit tests by calling Post, I'm using `Validator.TryValidateObject` inside the `TestMethod` and that's where it's failing to validate the nested model. – reggaemahn Aug 24 '16 at 06:31
  • Try with the updated link, http://stackoverflow.com/questions/7663501/dataannotations-recursively-validating-an-entire-object-graph – Smit Patel Aug 24 '16 at 06:38
  • I just tried that. Still doesn't work from the Test Method :( – reggaemahn Aug 24 '16 at 06:50