我很难找到一种方法来验证。net Core配置序列中的项目(尝试过。net 5和3.1)。
说我的设置是这样的:
{
"MyOpt": {
"IntOpt": 5,
"StrOpt": "...",
"Inner": {
"InnerStr": "...",
"InnerInt": 7
},
"Inners": [
{
"InnerStr": "...",
"InnerInt": 1
},
{
"InnerStr": "...",
"InnerInt": 2
}
]
}
}
public class Inner
{
public string InnerStr { get; set; }
[Range(0, 1000, ErrorMessage = "Value {0} must be between {1} and {2}")]
public int InnerInt { get; set; }
}
public class MyOpt
{
[Range(0, 1000, ErrorMessage = "Value {0} must be between {1} and {2}")]
public int IntOpt { get; set; }
public string StrOpt { get; set; }
public IEnumerable<Inner> Inners { get; set; }
}
我在startup。cs中这样配置:
services
.AddOptions<MyOpt>()
.Bind(Configuration.GetSection("MyOpt"))
.ValidateDataAnnotations();
当我试图访问它时,比如在WebAPI的控制器中:
public HomeController(ILogger<HomeController> logger, IOptions<OptOpt> options)
{
var whatever = options.Value.IntOpt;
_logger = logger;
}
验证正确启动MyOpt。IntOpt或MyOpt.Inner.InnerInt(数据注释和转换错误都会导致抛出异常,例如对于
{
"MyOpt": {
"IntOpt": "abc",
...
}
我得到了一个漂亮的
ArgumentException: abc is not a valid value for Int32. (Parameter 'value').
然而,如果其中一个MyOpt.Inners
项配置错误,它将被静默删除,例如对于
{
"MyOpt": {
// ...
"Inners": [
{
"InnerStr": "...",
"InnerInt": 1
},
{
"InnerStr": "...",
"InnerInt": "abc"
}
]
}
}
我在MyOpt中只得到一个项目。内部人(第一个)和我似乎找不到一种方式让它以某种方式"参与"。在验证-或绑定失败的"abc"通过异常报告。
任何想法?
默认情况下,验证属性不会进入集合内部并验证其内容,这就是为什么不调用集合中元素的属性的原因。
您可以实现IValidatableObject
并触发集合中项目的验证:
public class MyOpt : IValidatableObject
{
[Range(0, 1000, ErrorMessage = "Value {0} must be between {1} and {2}")]
public int IntOpt { get; set; }
public string StrOpt { get; set; }
public IEnumerable<Inner> Inners { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext){
var results = new List<ValidationResult>();
foreach (var item in this.Inners){
var validationResults = new List<ValidationResult>();
if (!Validator.TryValidateObject(item, new ValidationContext(item, validationContextItems), validationResults, true)))
{
results.AddRange(validationResults);
}
}
}
return result;
}
注意:代码是未经测试的,只是一个快速的建议,寻找IValidatableObject
和Validator
的文档。