自定义验证器并指定消息类型

时间:2010-03-29 19:37:35

标签: c# .net validation enterprise-library

我在企业验证块中进行了自定义验证。 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对象时,我需要识别并分组不同类型的消息并以不同方式呈现它们。

我的问题是 - 如何将失败标记为警告?

2 个答案:

答案 0 :(得分:2)

您可以使用Tag的{​​{1}}属性。 "The meaning for a tag is determined by the client code consuming the ValidationResults."

如果您正在使用配置,则可以在配置文件中指定标记:

ValidationResult


或者使用属性设置标记:

<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" />


如果您想以编程方式执行此操作,则必须创建新的验证结果,因为Tag属性是只读的:

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


然后在前端,您可以检查ValidationResult的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 ) );
}


显然,你可以更好地抽象,汇总错误和警告等。

<强>更新

我们对您的要求不一样,但我们做了类似的事情。不幸的是,我所知道的执行您正在讨论的条件验证类型的唯一方法是使用RuleSets。

我们所做的是使用RuleSet的命名约定并在运行时构造RuleSet Names。如果RuleSet存在,那么我们运行验证器。您可以为警告做类似的事情。所以你可以有两个RuleSet:

  • RuleSet_Salary_Update
  • RuleSet_Salary_Update_Warning

然后根据您是否要运行警告验证来检索验证器列表:

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

RuleSetType是一个包含不同类型规则的枚举(例如Select,Insert,Update,Delete,PrimaryKey等)。

答案 1 :(得分:1)

简答:

创建非默认规则集并将其命名为“警告”。

答案很长:

验证应用程序块支持“规则集”的概念。您可以创建名为“警告”的规则集。如何使用这取决于您的架构和界面,但这是一个想法。

这有点取决于您是否始终要显示错误和警告,或仅在出现错误时显示错误,否则显示警告或保存。当有警告时,用户需要能够说“我是肯定的,保存它!”然后你需要通过抑制错误来保存更改。

当您遵循此方法时,您可以抛出包含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);
    }
}

我希望这是有道理的。