![](/img/trans.png)
[英]Custom validation attribute to check for duplicates among my model properties is not firing
[英]Custom validation method that accesses other model properties
我試圖為我的一個實體創建自定義驗證方法,所以我創建了一個繼承自ValidationAttribute
的類:
public class OneWheelchairPerTrainAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
// This is where I need to access the other entity property
}
}
我正在努力的是如何訪問實體上的其他屬性。 這是我的實體:
public class Ticket
{
public int Id { get; set; }
[Required]
public int TimetableId { get; set; }
[Required]
public bool Wheelchair { get; set; }
public virtual Timetable Timetable { get; set; }
}
我正在編寫的驗證批注將應用於Wheelchair
屬性,並且需要從我的驗證方法中訪問TimetableId
屬性。
您可以使用IsValid重載來傳遞ValidationContext,如下所示:
public class OneWheelchairPerTrainAttribute : ValidationAttribute
{
public override bool IsValid(object value, ValidationContext context)
{
Object instance = context.ObjectInstance;
Type type = instance.GetType();
// Here is your timetableId
Object timeTableId = type.GetProperty("TimetableId ").GetValue(instance, null);
//Do validation ...
}
}
驗證多個屬性的另一種(我認為更好)的方法是在class
級別進行。
這與您的答案並不完全相同,但是仍然涉及多個屬性驗證。
假設您想讓輪椅成為ID或新對象,但您仍然只想允許一個輪椅:
我的ExactlyOneRequired
屬性的示例:
[AttributeUsage(AttributeTargets.Class)]
public class ExactlyOneRequiredAttribute : ValidationAttribute
{
public string FirstPropertyName { get; set; }
public string SecondPropertyName { get; set; }
//Constructor to take in the property names that are supposed to be checked
public ExactlyOneRequiredAttribute(string firstPropertyName, string secondPropertyName)
{
FirstPropertyName = firstPropertyName;
SecondPropertyName = secondPropertyName;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null)
return new ValidationResult("Object must have a value;");
var neededProperties = validationContext.ObjectType.GetProperties().Where(propertyInfo => propertyInfo.Name == FirstPropertyName || propertyInfo.Name == SecondPropertyName).Take(2).ToArray();
var value1 = neededProperties[0].GetValue(value);
var value2 = neededProperties[1].GetValue(value);
if (value1 == null | value2 == null)
return ValidationResult.Success;
return FailedValidationResult();
}
public override string FormatErrorMessage(string name) => $"One of the fields: '{FirstPropertyName} or {SecondPropertyName}' is required, it is not allowed to set both.";
private ValidationResult FailedValidationResult() => new ValidationResult(FormatErrorMessage(FirstPropertyName), new List<string> {FirstPropertyName, SecondPropertyName});
}
用法:
[ExactlyOneRequired(nameof(WheelChairId), nameof(WheelChair))]
public class Train
{
public int? WheelChairId { get; set; }
public WheelChair WheelChair { get; set; }
}
當然,您可以期望任意數量的屬性,並根據需要使其具有通用性 。 我的觀點是, 與其對屬性內的屬性名稱進行字符串檢查 ,不如注入屬性名稱是更干凈的方法,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.