c# - 当模型包含另一个类的对象作为使用 DataAnnotations 的属性时,如何在控制台应用程序中验证 .Net Core 3.1 中的模型?

标签 c# .net validation .net-core data-annotations

我有以下请求模型:

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

        [Required]
        [MaxLength(64)]
        public string PayerId { get; set; }
    }
我有如下自定义类:
 public class ProviderInfo
    {
        [Required]
        [MaxLength(15)]
        public string TaxId { get; set; }

        [Required(ErrorMessage = " Qualifier is required.")]
        [MaxLength(15)]
        public string NPI { get; set; }
    }
我目前正在使用 ValidationContext 进行模型验证:
var visitData = JsonConvert.DeserializeObject<VisitRequest>(jsonString);
var vc = new ValidationContext(visitData);
var errorResults = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(visitData, vc, errorResults, true);
我的演示 json 请求如下:
{
'Member': {
  'Qualifier': 'MedicaidID',
  'Identifier': '100'
  },                
  'ExternalVisitID': '123456789',
}
现在我在 ErrorResult 中收到 ErrorMessage 为:
PayerId is required.
但我没有得到自定义类的验证。如何在 .Net Core 控制台应用程序 中实现?
我对 .Net Core 还很陌生,所以任何帮助将不胜感激。谢谢!

更新:
我遵循了@John H 给出的答案,但仍然存在一个问题。
如果我的要求是:
'Provider' : {
      'TaxId' : null
}
它将正常工作,因为它能够识别这是 ProviderInfo 对象的类型。
但是,如果我的请求不包含有关 Provider 的任何信息:
{
'ExternalVisitID': '123456789',
'EVVMSID': '100', 
}
那么它就无法验证对象。

最佳答案

简而言之,这不起作用,因为 TryValidateObject 不支持复杂嵌套类型的验证。这也是该类型的 .NET Framework 版本的问题,@reustmd 创建了一个 NuGet Package 来解决该问题。不幸的是,它不支持 .NET Core,但我发现有一个 package forked from this 支持。从自述文件:

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 proposal 正在讨论将此功能添加到 .NET。如果您对该提案的技术设计讨论感兴趣,可以查看 .NET 基金会 discussing 发布的视频。
更新
对于上面的场景,我已经安装了上面的包,更改了 VisitRequest 类以使提供程序成为必需
public class VisitRequest
{
    [Required]
    public ProviderInfo Provider { get; set; }

    [Required]
    [MaxLength(64)]
    public string PayerId { get; set; }
}
然后运行以下命令:
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}");
    }
}
产生以下输出:
The Provider field is required.
    Provider
The PayerId field is required.
    PayerId
如果您想单独列出缺少的提供程序的每个字段,即使 JSON 的该部分为空,我认为您必须 fork NuGet 包并进行这些更改。但这可能是 .NET 没有立即支持此功能的原因,因为人们对其行为方式有不同的期望。

关于c# - 当模型包含另一个类的对象作为使用 DataAnnotations 的属性时,如何在控制台应用程序中验证 .Net Core 3.1 中的模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64009312/

相关文章:

c# - 在 csv 文件中使用字符串拆分和数组的 LINQ 问题

c# - 如何将变量限制为一组固定的字符串?

c# - Gridview 分页 ASP.NET 在 Gridview 之外使用寻呼机面板

c# - 具有不变名称 'Oracle.DataAccess.Client' 的 ADO.NET 提供程序未注册

java - 这两行的意思一样吗?

validation - Scala中的错误处理单子(monad)?尝试与验证

c# - 静态方法是否共享其局部变量以及在不同线程并发使用期间会发生什么?

c# - 重负载应用程序卡住

php - Laravel:验证表单中输入的名称

c# - 文件上传读取到内存并用作文本文件 - 有更好的方法吗?