Пользовательский валидатор и указание типа сообщения - PullRequest
3 голосов
/ 29 марта 2010

У меня есть пользовательская проверка в блоке проверки предприятия. Метод 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 ]

2 голосов
/ 30 марта 2010

Вы можете использовать Tag свойство ValidationResult. «Значение тега определяется клиентским кодом, использующим 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 ) );
}

Затем в интерфейсе вы можете проверить свойство Tag объекта ValidationResult, чтобы узнать, является ли это предупреждением:

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

Очевидно, вы можете абстрагироваться от этого гораздо лучше, объединить ошибки и предупреждения и т. Д.

ОБНОВЛЕНИЕ

У нас нет идентичных требований к вашим, но мы делаем что-то подобное.К сожалению, единственный известный мне способ выполнения условной проверки, о которой вы говорите, - это использование 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 - это перечисление с различными типами правил (например, Выбрать, Вставить, Обновить, Удалить, PrimaryKey и т. Д.).

1 голос
/ 30 марта 2010

Краткий ответ:

Создайте набор правил не по умолчанию и назовите его «Warning».

Длинный ответ:

Блок приложения валидации поддерживает понятие «набор правил». Вы можете создать набор правил с именем «Предупреждение». Как это использовать, зависит от вашей архитектуры и интерфейса, но вот идея.

Это немного зависит от того, хотите ли вы всегда отображать как ошибки, так и предупреждения, или показывать ошибки только при наличии ошибок, а также показывать предупреждения или сохранять. Когда есть предупреждения, пользователь должен иметь возможность сказать «черт возьми, да, я уверен, сохранить его!» а затем вам нужно сохранить изменения, подавив ошибки.

Когда вы следуете этому подходу, вы можете генерировать исключение (скажем, 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);
    }
}

Надеюсь, это имеет смысл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...