2010-03-29 121 views
2

我在企業驗證塊中有一個自定義驗證。 DoValidate方法如下所示。自定義驗證器和指定消息類型

protected override void DoValidate(Double objectToValidate, 
    object currentTarget, string key, ValidationResults validationResults) 
{ 
    if (!IsSalMoreThanMinWage(objectToValidate)) 
    { 
     //Here I need to mark this message as a "Warning" 
     LogValidationResult(validationResults, 
      "Salary is too low for this state", currentTarget, key); 
    } 
} 

我需要將此驗證失敗標記爲「警告」消息。在前端,當我遍歷ValidationResults集合並獲取ValidationResult對象時,我需要識別和分組不同類型的消息並以不同方式呈現它們。

我的問題是 - 如何將失敗標記爲警告?

回答

1

您可以使用ValidationResultTag屬性。"The meaning for a tag is determined by the client code consuming the ValidationResults."

如果您使用的配置,那麼你可以在配置文件中指定標籤:

<validator lowerBound="0" lowerBoundType="Inclusive" 
upperBound="255" upperBoundType="Inclusive" negated="false" messageTemplateResourceName="" messageTemplateResourceType="" 
messageTemplate="Oops a warning occurred" 
tag="Warning" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 
name="My Validator" /> 


或者與屬性設置標籤:

[StringLengthValidator(5, 50, Ruleset = "RuleSetA", Tag="Warning")] 


如果您想要以編程方式執行此操作,那麼您必須創建新的驗證結果,因爲Tag屬性是隻讀的:

ValidationResults newResults = new ValidationResults(); 

foreach (ValidationResult vr in validationResults) 
{ 
    newResults.AddResult(new ValidationResult( 
     vr.Message, vr.Target, vr.Key, "Warning", vr.Validator, vr.NestedValidationResults)); 
} 


然後在前端,您可以檢查的ValidationResult的Tag屬性,看它是否是一個警告:

foreach (ValidationResult vr in validationResults) 
{ 
    if (string.Compare(vr.Tag, "Warning") == 0) 
    { 
     DisplayWarning(vr.Message); 
    } 
    else 
    { 
     DisplayError(vr.Message); 
    } 
} 


很明顯,你可以抽象不過如此,聚集的錯誤和警告等

UPDATE

我們對您的要求並不完全相同,但我們的工作類似。不幸的是,我知道執行您所談論的條件驗證的唯一方式就是使用RuleSets。

我們所做的是對RuleSets使用命名約定,並在運行時構造RuleSet名稱。如果RuleSet存在,那麼我們運行驗證器。你可以爲你的警告做類似的事情。所以,你可以有兩個規則集:

  • RuleSet_Salary_Update
  • RuleSet_Salary_Update_Warning

,然後檢索校驗的基礎上,你是否要運行警告驗證列表:

public static List<Validator<T>> CreateValidators<T>(bool shoulIncludeWarning, RuleSetType rulesetType) 
    { 
     if (shouldIncludeWarning) 
     { 
      // Get warning validator if any 
     } 

     // Get Default validator (if any) 
    } 

RuleSetType是具有不同類型規則的枚舉(例如Select,Insert,Update,Delete,PrimaryKey等)。

+0

@Tuzo - 是的,這是我最終做的。我本來希望VAB製造商使用不同的數據類型作爲標籤。我想使用枚舉,但最終不得不做一些將字符串標籤轉換爲枚舉的骯髒工作。 就像史蒂文指出的那樣,一旦用戶壓制警告,我需要一種方法來再次運行驗證,但現在忽略警告。我想在不使用規則集的情況下這樣做(除非有一種爲單個驗證程序指定多個規則集的方法) – Nick 2010-03-30 13:38:43

+0

@Tuzo - 關於您的更新 - 您說「爲規則集使用命名約定並在運行時構建它們」 你是否在運行時命名規則集? – Nick 2010-03-30 18:02:19

+0

對不起,我很清楚,我正在討論在運行時使用命名約定來構造RuleSet **名稱**。不自動創建RuleSets。 – 2010-03-30 18:31:03

0

簡短的回答:

創建一個非默認規則集並將其命名爲「警告」。

龍答:

驗證應用程序塊支持 '規則集' 的概念。您可以製作一個名爲「警告」的規則集。如何使用這取決於你的架構和界面,但這是一個想法。

這有點取決於您是否總是要顯示錯誤和警告,或者只有在出現錯誤時才顯示錯誤,否則顯示警告或保存。當有警告時,用戶需要能夠說出「我確定,我確定,保存它!」然後您需要通過抑制錯誤來保存更改。

當你遵循這種方法時,你可以拋出一個異常(比如ValidationException)來保存ValidationResult對象。將屬性添加到異常中,說明結果是警告還是錯誤(當您決定在出現錯誤時不顯示任何警告時,可以執行此操作)。

在表示層,你做到以下幾點:

Button_Save(object sender, EventArgs e) 
{ 
    this.Save(ValidationMode.Default); 
} 

Button_HellYesSuppresWarningsAndSave(object sender, EventArgs e) 
{ 
    this.Save(ValidationMode.SuppressWarnings); 
} 


private Save(ValidationMode mode) 
{ 
    try 
    { 
     ServiceLayer.Save(mode); 
    } 
    catch (ValidationException ex) 
    { 
     if (ex.ResultType == ValidationResultType.Warnings) 
     { 
      ShowWarningsAndAskIfSure(ex.Errors); 
     } 
     else 
     { 
      ShowErrorsAndTellUserNeedsToFix(ex.Errors); 
     } 
    } 
} 

在你需要的東西像這樣的業務層:

public void Save(ValidationMode mode) 
{ 
    Validate(ValidationResultType.Errors); 

    if (!mode == ValidationMode.SuppressWarnings) 
    { 
     Validate(ValidationResultType.Warnings); 
    } 
} 

private void Validate(ValidationResultType type) 
{ 
    var objectToValidate; 
    var ruleset = type == ValidationResultType.Errors ? "default" : "warnings"; 
    var validator = ValidationFactory 
     .CreateValidator(objectToValidate.GetType(), ruleset); 

    var results = validator.Validate(); 
    if (!results.IsValid) 
    { 
     throw new ValidationException(results, type); 
    } 
} 

我希望這是有道理的。

+0

@Steven - 這與我試圖實現的類似。但是,我已經在使用規則集來根據業務規則定義其他分組。除了規則集,還有其他方式可以說 - 嘿,用戶已經禁止了警告,所以不要運行任何標記爲警告的驗證?我遇到的另一個問題是我添加的代碼片段是我正在處理的自定義驗證器的子集。我正在做的一個有兩個驗證--1是警告,1是錯誤。兩者都包含在DoValidate方法中。在我看來,這個驗證器需要分裂成錯誤和警告 – Nick 2010-03-30 13:36:48

+0

@Steven - 一個無關的問題。如果結果無效,爲什麼會拋出異常?雖然這有效,但我總是在極端情況下拋出異常,代碼無法恢復。其中一個副作用是,如果您在應用程序中使用任何日誌記錄塊,那麼所有這些異常都會記錄在日誌中。 – Nick 2010-03-30 13:58:38

+0

@ user102533:「還有其他方式不要運行任何標記爲警告的驗證嗎?」。據我所知,沒有其他方法可以將驗證標記爲警告。我認爲規則集是唯一可行的方法。 – Steven 2010-03-30 19:30:43