提问人:Ilya Chernomordik 提问时间:10/11/2023 最后编辑:Ilya Chernomordik 更新时间:10/12/2023 访问量:58
如何增强 ASP.NET 核心验证以忽略某些属性并验证作为该属性函数的值?
How to augment the ASP.NET Core validation to ignore some properties and validate on a value that is a function of that property?
问:
我有一堂课取自 Roslyn:https://github.com/dotnet/roslyn/blob/main/src/Compilers/Core/Portable/Optional.csOptional
它的要点:
public readonly struct Optional<T>
{
public Optional(T value)
{
_hasValue = true;
_value = value;
}
public bool HasValue => _hasValue;
public T Value => _hasValue
? _value
: throw new InvalidOperationException("Optional object must have a value");
}
现在,我想在 ASP.NET 请求模型中使用此类,以便用户可以在更新请求期间设置该模型的任意属性以执行部分更新。
这本身工作正常,我得到了一个合适的模型,但是当我想添加验证(而不是重用标准验证)属性时,问题就出现了。
弹出这两个问题:
- 验证尝试读取并在未设置字段时引发异常(当它尝试访问子项时)
Value
- 如果设置了该字段,则验证属性将无法正确获取,并会尝试验证结构本身
Value
我不确定我是否试图正确解决它,但我想知道我是否可以以某种方式更改字段或包含此类字段的对象的验证,以便验证中忽略所有未设置的字段,并且设置的字段将验证而不是结构本身。Optional
.Value
P.S. 我不能使用,因为我想区分空值和没有值。即具有 null 值的字段表示:将字段更新为 ,no field 表示 - 不要更改该字段。这是尝试对 json 中的未定义进行建模。因此,例如,如果相应的字段可以接受 null,我将有 Optional<string?> 和 Optional<long?>。Nullable<T>
null
答:
0赞
Ale_Bianco
10/12/2023
#1
您可以尝试使用自定义验证属性:
- 创建可以处理该类型的自定义验证属性。此属性将检查 是否具有值,如果有,它将验证 .
Optional<T>
Optional<T>
Value
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class OptionalValidationAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var optional = value as dynamic; // Use dynamic to access HasValue and Value
if (optional != null && optional.HasValue)
{
var validationResult = base.IsValid(optional.Value, validationContext);
if (validationResult != ValidationResult.Success)
{
return validationResult;
}
}
return ValidationResult.Success;
}
}
- 将 应用于请求模型中类型为 的属性。
OptionalValidationAttribute
Optional<T>
public class UpdateRequestModel
{
[OptionalValidation]
public Optional<string> Name { get; set; }
[OptionalValidation]
public Optional<int> Age { get; set; }
}
- 现在,当您在 ASP.NET 操作中执行模型验证时,将应用于 类型的属性。它将检查 是否有值,如果有,它将验证 .
OptionalValidationAttribute
Optional<T>
Optional<T>
Value
[HttpPost]
public IActionResult Update([FromBody] UpdateRequestModel model)
{
if (!ModelState.IsValid)
{
// Handle invalid model
return BadRequest(ModelState);
}
// Process valid model
// ...
}
评论
0赞
Ilya Chernomordik
10/12/2023
我不太明白在这种情况下如何进行真正的验证?只有当我想对每个可选字段应用完全相同的验证时,这才有效,但事实并非如此。
评论
Option<T>
null
undefined
Nullable<T>
struct
undefined
null
Option<T>