如何增强 ASP.NET Core 验证以忽略某些属性并验证作为该属性函数的值?

问题描述 投票:0回答:1

我有一个从 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 请求模型中使用此类,以便用户可以在更新请求期间设置所述模型的任意属性以执行部分更新。

这本身工作得很好,我得到了一个正确的模型,但是当我想添加验证(而不是重新使用标准验证)属性时,问题就出现了。

出现这两个问题:

  1. 当字段未设置时,验证会尝试读取
    Value
    并抛出异常(当它尝试访问子级时)
  2. 如果设置了该字段,验证属性将无法正确获取
    Value
    并会尝试验证结构本身

我不确定我是否正在尝试正确解决它,但我想知道是否可以以某种方式更改

Optional
字段或包含此类字段的对象的验证,以便忽略所有未设置的字段来自验证,并且设置的内容将在
.Value
而不是结构本身进行验证。

附注我不能使用

Nullable<T>
,因为我想区分空值和不存在值。 IE。具有空值的字段表示:将该字段更新为
null
,无字段表示 - 不更改该字段。这是尝试从 json 中对未定义进行建模。所以例如如果相应字段可以接受 null,我将拥有可选和可选

c# asp.net-core validation .net-core model-binding
1个回答
0
投票

您可以尝试使用自定义验证属性:

  • 创建可以处理
    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
    // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.