简体   繁体   中英

How to validate model in .Net Core 3.1 in console app when the model contains another class's object as a property using DataAnnotations?

I have the following request model:

public class VisitRequest
    {
        public ProviderInfo Provider { get; set; }

        [Required]
        [MaxLength(64)]
        public string PayerId { get; set; }
    }

And i have the custom class as follows:

 public class ProviderInfo
    {
        [Required]
        [MaxLength(15)]
        public string TaxId { get; set; }

        [Required(ErrorMessage = " Qualifier is required.")]
        [MaxLength(15)]
        public string NPI { get; set; }
    }

I am currently using ValidationContext to do the model validations:

var visitData = JsonConvert.DeserializeObject<VisitRequest>(jsonString);
var vc = new ValidationContext(visitData);
var errorResults = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(visitData, vc, errorResults, true);

My demo json request is as follows:

{
'Member': {
  'Qualifier': 'MedicaidID',
  'Identifier': '100'
  },                
  'ExternalVisitID': '123456789',
}

Now I am receiving the ErrorMessage in ErrorResult as:

PayerId is required.

But I am not getting the validations of the custom class. How to implement this in .Net Core Console application ? I am quite new to.Net Core so any help would be appreciated.Thanks!


UPDATE:

I followed the answer given by @John H but still there is one issue.

If my request is:

'Provider' : {
      'TaxId' : null
}

it will work fine, because it is able to identify that this is the type ProviderInfo object.

But if my request does not contain any info regarding the Provider:

{
'ExternalVisitID': '123456789',
'EVVMSID': '100', 
}

then it is not able to validate the object.

In brief, this doesn't work because TryValidateObject doesn't support the validation of complex nested types. This was also an issue for the .NET Framework version of this type, and @reustmd created a NuGet Package to solve the problem. Unfortunately, it doesn't support .NET Core, but I found there is a package forked from this which does. From the readme:

Installation

Available as NuGet-Package dataannotationsvalidator :

Install-Package dataannotationsvalidator

Usage

See file DataAnnotationsValidator/DataAnnotationsValidator.Tests/DataAnnotationsValidatorTests.cs

Short example:

var validator = new DataAnnotationsValidator.DataAnnotationsValidator();

var validationResults = new List<ValidationResult>();

validator.TryValidateObjectRecursive(modelToValidate, validationResults);

This should solve your problem.

As an aside, I also found this proposal discussing adding this functionality to .NET. If you're interested in a technical design discussion of that proposal, there is a video posted by the .NET Foundation discussing it.

Update

For your scenario above, I've installed the above package, changed the VisitRequest class to make the provider required

public class VisitRequest
{
    [Required]
    public ProviderInfo Provider { get; set; }

    [Required]
    [MaxLength(64)]
    public string PayerId { get; set; }
}

and then ran the following:

var jsonString = @"{
    ""ExternalVisitID"": ""123456789"",
    ""EVVMSID"": ""100""
}";

var modelToValidate = JsonConvert.DeserializeObject<VisitRequest>(jsonString);

var validator = new DataAnnotationsValidator.DataAnnotationsValidator();

var validationResults = new List<ValidationResult>();

validator.TryValidateObjectRecursive(modelToValidate, validationResults);

foreach (var item in validationResults)
{
    Console.WriteLine(item.ErrorMessage);

    foreach (var memberName in item.MemberNames)
    {
        Console.WriteLine($"\t{memberName}");
    }
}

which produces output of:

The Provider field is required.
    Provider
The PayerId field is required.
    PayerId

If you're wanting to list each field of a provider that's missing individually, even though that part of the JSON is empty, I think you'll have to fork the NuGet package and make those changes. But this is probably a reason why .NET hasn't supported this functionality out of the box, because people have different expectations for how it should behave.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM