英文:
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 IEnumerable
s.
I used the existing RangeAttribute
like this:
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;
}
}
and annotated my Parameter like this:
[RangeEnumerable(MINIMUM_ANGLE, MAXIMUM_ANGLE)]
public IEnumerable<Double> PhaseAnglesVoltage { get; set; } = new List<double>();
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<ValidationResult>();
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()
,然后使用List
的Add()
方法来更改源代码。
英文:
I created one console app based on your code.
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();
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论