你可以如何使用 ASP.NET 的 [Range] 注解来处理 IEnumerable 元素?

huangapple go评论79阅读模式
英文:

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

问题

我想使用ASP.NET的[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;
}

我期望循环迭代我使用注解的列表的元素,但是在IsValid函数中,我始终得到一个空列表,而不是在测试中附加了元素的列表。

英文:

I want to use the ASP.NET [Range] Annotation but for the elements IEnumerables.

I used the existing RangeAttribute like this:

public class RangeEnumerable : RangeAttribute
{
	/// &lt;inheritdoc/&gt;
	public RangeEnumerable(double minimum, double maximum) : base(minimum, maximum)
	{
	}

	/// &lt;inheritdoc/&gt;
	public RangeEnumerable(int minimum, int maximum) : base(minimum, maximum)
	{
	}

	/// &lt;inheritdoc/&gt;
	public RangeEnumerable([DynamicallyAccessedMembers((DynamicallyAccessedMemberTypes)(-1))] Type type, string minimum, string maximum) : base(type, minimum, maximum)
	{
	}

	/// &lt;inheritdoc/&gt;
	public override bool IsValid(object? value)
	{
		if (null == value) { return true; } 

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

		return true;
	}
}

and annotated my Parameter like this:

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

And wrote the following unit test:

[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&lt;ValidationResult&gt;();
	Validator.TryValidateObject(obj, validationContext, validationResults, true);
	return validationResults.Count;
}

I expected the loop to iterate over the elements of the List I used the annotation with, but in the IsValid-Function I always get an empty List instead of one with the element appended in the test.

答案1

得分: 0

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

将单元测试更改为以下内容即可解决问题。

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

    // 执行
    var errCount = ValidateObject(loadpoint1);
   
    // 断言
    Assert.AreEqual(1, errCount);
}
英文:

Ok, I've found the error, which was in the unit test. IEnumerable.Append doesn't add the element to the original object like List.Add does (see Difference between a List's Add and Append method?).

Changing the unit test to the following does the trick.

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

答案2

得分: 0

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

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

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

我认为您所做的更改没有按预期工作。您需要使用toList()或将IEnumerable分配给new List(),然后使用ListAdd()方法来更改源代码。

英文:

I created one console app based on your code.

你可以如何使用 ASP.NET 的 [Range] 注解来处理 IEnumerable 元素?

on line no 8 as you can see and as you said it does not change the source. But after modifying to below line will create another object from that yielded IEnumerable

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

你可以如何使用 ASP.NET 的 [Range] 注解来处理 IEnumerable 元素?

I think the change you made is not working as expected. You need to do toList() or assign IEnumerable with new List() and then use Add() method of List which will change the source.

huangapple
  • 本文由 发表于 2023年6月1日 22:04:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76382755.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定