![](/img/trans.png)
[英]How do I make a class library that works in ASP.NET and non-ASP.NET applications?
[英]How can I use the Data Validation Attributes in C# in a non-ASP.net context?
我想在庫程序集中使用數據驗證屬性,這樣數據的任何使用者都可以在不使用ModelBinder的情況下對其進行驗證(例如,在控制台應用程序中)。 我該怎么做?
其實這很酷。 我最近在WFP驗證實施中使用它。 大多數人最終使用反射來編寫大量代碼來迭代屬性,但是有一個內置函數。
var vc = new ValidationContext(myObject, null, null);
return Validator.TryValidateObject(myObject, vc, null, true);
您還可以在單個命名屬性上驗證屬性。 您還可以選擇傳入列表以訪問錯誤消息:
var results = new List<ValidationResult>();
var vc = new ValidationContext(myObject, null, null) { MemberName = "UserName"};
var isValid = Validator.TryValidateProperty(value, vc, results);
// get all the errors
var errors = Array.ConvertAll(results.ToArray(), o => o.ErrorMessage);
System.ComponentModel.DataAnnotations.ValidationAttribute
類具有執行驗證邏輯的IsValid
方法。 它們獲取一個Object(它們裝飾的字段的值)並返回true
或false
。
您可以使用這些屬性和一些反射來推動您自己的面向方面的驗證器。 將驗證器傳遞給對象,驗證器將獲得PropertyInfo
和FieldInfo
的列表。 對於其中的每一個,它可以調用GetCustomAttributes
來查找從ValidationAttribute
繼承的那些,並為每個調用IsValid
,傳遞屬性或字段的值。 這可以完全動態地完成,而不需要知道要在設計時驗證的類的結構。
TryValidateProperty
編寫得很糟糕 - 你必須通過箍來讓它在Controller之外工作,即使這樣,如果你使用它兩次,它最終會安靜地將ModelState設置為有效/無效並停止改變該狀態,並停止從那時起返回准確的結果。
我放棄了它,只是寫了我自己的驗證器。 這將循環遍歷任何上下文中的任何對象集,並告訴您它們是否有效:
bool isValid = true;
var invalidFields = new List<string>();
foreach (var o in viewModels)
{
var properties = o.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach(var prop in properties)
{
var attrs = prop.GetCustomAttributes(true);
if (attrs != null)
{
var val = prop.GetValue(o);
ValidationAttribute[] validatorAttrs = attrs
.Where(a => a is ValidationAttribute)
.Select(a => (ValidationAttribute)a).ToArray();
foreach(var attr in validatorAttrs)
{
bool thisFieldIsValid = attr.IsValid(val);
if (!thisFieldIsValid)
invalidFields.Add(prop.Name);
isValid = isValid && thisFieldIsValid;
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.