我有一个从 Roslyn 获取的
Optional
课程:https://github.com/dotnet/roslyn/blob/main/src/Compilers/Core/Portable/Optional.cs
要点:
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
而不是结构本身进行验证。
附注我不能使用
Nullable<T>
,因为我想区分空值和不存在值。 IE。具有空值的字段表示:将该字段更新为 null
,无字段表示 - 不更改该字段。这是尝试从 json 中对未定义进行建模。所以例如如果相应字段可以接受 null,我将拥有可选您可以尝试使用自定义验证属性:
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; }
}
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
// ...
}