当模型包含另一个 class 的对象作为 属性 使用 DataAnnotations 时,如何在控制台应用程序中验证 .Net Core 3.1 中的模型?
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?
我有以下请求模型:
public class VisitRequest
{
public ProviderInfo Provider { get; set; }
[Required]
[MaxLength(64)]
public string PayerId { get; set; }
}
我的自定义 class 如下:
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.
但我没有得到自定义 class 的验证。如何在 .Net Core Console 应用程序 中实现?
我是 .Net Core 的新手,所以任何帮助都是 appreciated.Thanks!
更新:
我按照@John H 给出的答案进行了操作,但仍然存在一个问题。
如果我的要求是:
'Provider' : {
'TaxId' : null
}
它将正常工作,因为它能够识别这是 ProviderInfo 对象类型。
但是如果我的请求不包含任何关于提供商的信息:
{
'ExternalVisitID': '123456789',
'EVVMSID': '100',
}
那么它就无法验证对象。
简而言之,这不起作用,因为 TryValidateObject
不支持复杂嵌套类型的验证。对于这种类型的 .NET Framework 版本,这也是一个问题,@reustmd 创建了一个 NuGet Package to solve the problem. Unfortunately, it doesn't support .NET Core, but I found there is a 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 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。
更新
对于上面的场景,我已经安装了上面的包,更改了 VisitRequest
class 以使提供程序成为必需的
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 的那部分是空的,我认为您必须分叉 NuGet 包并进行这些更改.但这可能是 .NET 不立即支持此功能的原因,因为人们对它的行为方式有不同的期望。
我有以下请求模型:
public class VisitRequest
{
public ProviderInfo Provider { get; set; }
[Required]
[MaxLength(64)]
public string PayerId { get; set; }
}
我的自定义 class 如下:
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.
但我没有得到自定义 class 的验证。如何在 .Net Core Console 应用程序 中实现? 我是 .Net Core 的新手,所以任何帮助都是 appreciated.Thanks!
更新:
我按照@John H 给出的答案进行了操作,但仍然存在一个问题。
如果我的要求是:
'Provider' : {
'TaxId' : null
}
它将正常工作,因为它能够识别这是 ProviderInfo 对象类型。
但是如果我的请求不包含任何关于提供商的信息:
{
'ExternalVisitID': '123456789',
'EVVMSID': '100',
}
那么它就无法验证对象。
简而言之,这不起作用,因为 TryValidateObject
不支持复杂嵌套类型的验证。对于这种类型的 .NET Framework 版本,这也是一个问题,@reustmd 创建了一个 NuGet Package to solve the problem. Unfortunately, it doesn't support .NET Core, but I found there is a 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 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。
更新
对于上面的场景,我已经安装了上面的包,更改了 VisitRequest
class 以使提供程序成为必需的
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 的那部分是空的,我认为您必须分叉 NuGet 包并进行这些更改.但这可能是 .NET 不立即支持此功能的原因,因为人们对它的行为方式有不同的期望。