. 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")]

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

您可以为这种情况实现您自己的自定义验证属性。

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

您必须将bool标志(复选框打开或关闭)以及范围值作为自定义类的"输入"。

应该是这样的:

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;
}
}

仅使用if进行验证。

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

不能使用Attribute作为语句。这是宣言的一部分。使用属性在(类/字段/方法/参数等)声明中添加一些元数据,并使用反射读取这些数据。

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


阅读关于c#属性和数据注释的内容。

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

如果你坚持或认为安全性可能会被破坏,并且想要在服务器端验证所有情况,你可以通过扩展。net ValidationAttribute类来创建一个自定义验证属性:

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

一个关于如何使用它的例子:ASP。. NET MVC:使用DataAnnotation自定义验证

如果你在Core . net中编写API,是的,正如Wootiae所说,你可以抛出一个异常,让Core . net返回一个范围为400的HTTP代码,这表示"格式不好"。这应该在API方法BODY中完成。像这样:

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

无论如何,前端代码仍然应该强制执行。

如pinkfloydx33所示