我需要编写一个通用的验证注释,根据集合中对象的某些属性来检查集合的所有元素是否都是唯一的。
例如,它需要验证任务列表中的所有任务名称是唯一的:
class Task
{
public string TaskName {get; set;}
public bool TaskIsComplete {get; set;}
...
}
[UniqueElementsRequired(ErrorMessage = "Task names must be unique")]
List<Task> TaskList {get; set;}
问题在于它必须是通用的,所以我不知道如何指定使用哪些属性作为构成“唯一”的决定因素。
基本上我想做类似的事情:
[UniqueElementsRequired(TaskList.Select(x => x.TaskName), ErrorMessage = "Task names must be unique")]
List<Task> TaskList {get; set;}
我可以使用任务名称列表。但是我无法找到传递这样的附加列表的方法。
答案 0 :(得分:0)
经过一些搜索和实验,我找到了一种方法来访问存储在集合中的对象的属性,我试图从验证注释中进行验证。诀窍是构造函数并获得您想要的PropertyInfo。保持一般化是有点棘手的。
public class UniqueElementsRequiredAttribute : ValidationAttribute
{
/// <summary>
/// Initializes a new instance of the UniqueElementsRequiredAttribute class.
/// </summary>
/// <param name="typeOfCollectionElements">Type of the elements in the collection. Leave as null if testing the elements directly rather than one of their properties.</param>
/// <param name="nameOfPropertyToTestForUniqueness">Name of element property desired to be unique. Leave as null if testing the elements directly rather than one of their properties. MUST BE EXACT.</param>
public UniqueElementsRequiredAttribute(Type typeOfCollectionElements = null, string nameOfPropertyToTestForUniqueness = null)
{
NameOfPropertyToTestForUniqueness = nameOfPropertyToTestForUniqueness;
TypeOfCollectionElements = typeOfCollectionElements;
}
private string NameOfPropertyToTestForUniqueness { get; set; }
private Type TypeOfCollectionElements { get; set; }
public override bool IsValid(object value)
{
var collection = value as IEnumerable;
if (collection == null)
{
return true;
}
var listToTestForUniqueness = CreateListToTestForUniqueness(collection);
int countOfAllElements = listToTestForUniqueness.Count();
int countOfDistinctElements = listToTestForUniqueness.Distinct().Count();
return countOfAllElements == countOfDistinctElements;
}
private List<object> CreateListToTestForUniqueness(IEnumerable collection)
{
var listToTestForUniqueness = new List<object>();
if (NameOfPropertyToTestForUniqueness != null && TypeOfCollectionElements != null)
{
// Trick 1
PropertyInfo propertyInfoOfPropertyToTestForUniqueness = TypeOfCollectionElements.GetProperty(NameOfPropertyToTestForUniqueness);
foreach (var element in collection)
{
// Trick 2
listToTestForUniqueness.Add(propertyInfoOfPropertyToTestForUniqueness.GetValue(element));
}
}
else
{
listToTestForUniqueness = collection.Cast<object>().ToList();
}
return listToTestForUniqueness;
}
}
验证注释将标记为以下内容:
[UniqueElementsRequired(typeof(Task), "TaskName", ErrorMessage = "Task names must be unique")]
public object TaskList { get; set; }
如果有人能想出一个更优雅的方式来解决这个问题,请告诉我,但它到目前为止还有效。