如何对 IEnumerable 元素使用 ASP.NET [Range] 批注?

How can I use the ASP.NET [Range] annotation for IEnumerable elements?

提问人:Florian B. 提问时间:6/1/2023 最后编辑:FlorianFlorian B. 更新时间:6/2/2023 访问量:49

问:

我想使用 ASP.NET 注释,但对于元素 s。[Range]IEnumerable

我使用了现有的,如下所示:RangeAttribute

public class RangeEnumerable : RangeAttribute
{
    /// <inheritdoc/>
    public RangeEnumerable(double minimum, double maximum) : base(minimum, maximum)
    {
    }

    /// <inheritdoc/>
    public RangeEnumerable(int minimum, int maximum) : base(minimum, maximum)
    {
    }

    /// <inheritdoc/>
    public RangeEnumerable([DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type type, string minimum, string maximum) : base(type, minimum, maximum)
    {
    }

    /// <inheritdoc/>
    public override bool IsValid(object? value)
    {
        if (null == value) { return true; } 

        IEnumerable<object> list = ((IEnumerable)value).Cast<object>();
        
        foreach (object item in list)
        {
            if (!base.IsValid(item))
            {
                return false;
            }                
        }

        return true;
    }
}

并像这样注释我的参数:

[RangeEnumerable(MINIMUM_ANGLE, MAXIMUM_ANGLE)]
public IEnumerable<Double> PhaseAnglesVoltage { get; set; } = new List<double>();

并编写了以下单元测试:

[Test]
public void TestInvalidPhaseAngleVoltageTooLow()
{
    // Arrange       
    Loadpoint loadpoint1 = new Loadpoint();
    loadpoint1.PhaseAnglesVoltage.Append(-1);

    // Act
    var errCount = ValidateObject(loadpoint1);

    // Assert
    Assert.AreEqual(1, errCount);
}

private int ValidateObject(object obj)
{
    var validationContext = new ValidationContext(obj, null, null);
    var validationResults = new List<ValidationResult>();
    Validator.TryValidateObject(obj, validationContext, validationResults, true);
    return validationResults.Count;
}

我希望循环遍历我使用注解的 List 元素,但在 -Function 中,我总是得到一个空的 List,而不是一个在测试中附加了元素的 List。IsValid

C# asp.net 验证 批注

评论

0赞 DavidG 6/1/2023
反正我不会在这里使用。这只是一个合约,意思是“这是你可以迭代的东西”,但理论上它可以包含一个永无止境的值序列。为什么不直接选择或?IEnumerable<T>ICollection<T>List<T>
0赞 Florian B. 6/1/2023
因为不存在,如果我是对的,这里需要一个我不知道的类型参数(也许我只是不知道如何在这里正确使用它)。ICollection.CastList

答:

0赞 Florian B. 6/1/2023 #1

好的,我发现了单元测试中的错误。 不会像 Do 那样将元素添加到原始对象中(请参阅 List 的 Add 和 Append 方法之间的区别?)。IEnumerable.AppendList.Add

将单元测试更改为以下内容就可以了。

        [Test]
        public void TestInvalidPhaseAngleVoltageTooLow()
        {
            // Arrange       
            Loadpoint loadpoint1 = new Loadpoint();
            loadpoint1.PhaseAnglesVoltage = loadpoint1.PhaseAnglesVoltage.Append(-1);

            // Act
            var errCount = ValidateObject(loadpoint1);
   
            // Assert
            Assert.AreEqual(1, errCount);
        }
0赞 Kunal 6/2/2023 #2

我根据你的代码创建了一个控制台应用。

enter image description here

如您所见,在第 8 行,正如您所说,它不会更改源。但是在修改到以下行后,将从生成的 IEnumerable 创建另一个对象

model.Doubles = model.Doubles.Append(1.1).toList();

enter image description here

我认为您所做的更改没有按预期工作。您需要执行 toList() 或使用新的 List() 分配 IEnumerable,然后使用 List 的 Add() 方法,这将更改源。