.Net Core 中的条件范围数据注释

Conditional Range Data Annotation in .Net Core

我正在尝试使用数据注释来验证 .Net Core 中的数字。如果用户选中类型复选框,数字必须介于 0.5 和 20 之间,否则介于 0.5 和 100 之间。 有没有办法使用范围数据注释?

喜欢:

if (type)
 [Range(0.5, 20, ErrorMessage = "<20")]
else
 [Range(0.5, 100, ErrorMessage = "<100")]

或者有什么办法可以做到这一点?

仅使用 if 进行验证。

if (value < 0.5)
  throw new ArgumentOutOfRangeException();

if (type)
{
  if (value > 20)
    throw new ArgumentOutOfRangeException();
}
else 
{
  if (value > 100)
    throw new ArgumentOutOfRangeException();
}

您不能将 Attribute 用作语句。它是声明的一部分。使用属性将一些元数据添加到 (class/field/method/argument/etc) 声明并使用反射读取此数据。

数据注释可用于验证或静态分析。


了解 Attributes in C# and Data annotations

从技术上讲,我更喜欢在前端执行这种条件验证。服务器端验证通常只是出于安全原因,作为最后的手段或基本验证:不要让用户注入土豆而不是整数。 因此,如果您验证足够的最大范围边界 如果从安全角度来看语义验证并不重要

如果您坚持或认为安全性会被破坏,并希望在服务器端验证所有情况,您可以通过扩展 .NET ValidationAttribute class:

创建自定义验证属性

https://docs.microsoft.com/de-de/dotnet/api/system.componentmodel.dataannotations.validationattribute?view=net-5.0

这里有一个关于如何使用它的例子: ASP.NET MVC: Custom Validation by DataAnnotation

如果你在 Core .NET 中写一个 API 是的,正如 Wootiae 所说,你可以抛出一个异常并让 Core .NET return 一个 400 范围内的 HTTP 代码,它表示“格式错误”。这应该在 API 方法 BODY 中完成。 像这样:

if (condition)
    return HttpBadRequest("Bad Request. Out of Range.");

无论如何,前端代码仍应执行此操作。

已编辑

根据 pinkfloydx33 的建议

对于这种情况,您可以实施自己的自定义验证属性。

查看 https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-5.0#custom-attributes

对于该自定义 class.

,您必须将 bool 标志(复选框打开或关闭)以及范围值作为 'inputs'

应该是这样的:

public class NumberRangeByConditionAttribute : ValidationAttribute
{
    float _minRange, _maxRange;

    public NumberRangeByConditionAttribute (bool isChecked, float minWhenChecked, float maxWhenChecked, float minWhenUnchecked, float maxWhenUnchecked)
    {
        if (isChecked) 
        {
            _minRange = minWhenChecked;
            _maxRange = maxWhenChecked;
        }
        else 
        {
            _minRange = minWhenUnchecked;
            _maxRange = maxWhenUnchecked;
        }
    }

    public string GetErrorMessage() =>
        $"Number should be between {_minRange} and {_maxRange}.";

    protected override ValidationResult IsValid(object value,
        ValidationContext validationContext)
    {
        var number = (float)validationContext.ObjectInstance;

        if (number > _maxRange || number < _minRange)
        {
            return new ValidationResult(GetErrorMessage());
        }

        return ValidationResult.Success;
    }
}