Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Валидация действий предоставляет метод для выявления и сообщения об ошибках в конфигурации любой активности до её выполнения. Проверка возникает, когда рабочий процесс изменяется в конструкторе рабочих процессов, а все ошибки проверки или предупреждения отображаются в конструкторе рабочих процессов. Проверка также происходит во время выполнения при вызове рабочего процесса и при возникновении каких-либо ошибок проверки, InvalidWorkflowException вызывается логикой проверки по умолчанию. Windows Workflow Foundation (WF) предоставляет ActivityValidationServices класс, который может использоваться приложением рабочего процесса и разработчиками инструментов для явной проверки действия. В этом разделе описывается, как использовать ActivityValidationServices для проверки активности.
Использование ActivityValidationServices
ActivityValidationServices имеет две Validate перегрузки, которые используются для вызова логики проверки активности. Первая перегрузка принимает корневое действие, которое необходимо проверить, и возвращает коллекцию ошибок проверки и предупреждений. В следующем примере используется настраиваемое Add действие с двумя обязательными аргументами.
public sealed class Add : CodeActivity<int>
{
[RequiredArgument]
public InArgument<int> Operand1 { get; set; }
[RequiredArgument]
public InArgument<int> Operand2 { get; set; }
protected override int Execute(CodeActivityContext context)
{
return Operand1.Get(context) + Operand2.Get(context);
}
}
Действие Add используется внутри Sequence, но два его обязательных аргумента не привязаны, как показано в следующем примере.
Variable<int> Operand1 = new Variable<int>{ Default = 10 };
Variable<int> Operand2 = new Variable<int>{ Default = 15 };
Variable<int> Result = new Variable<int>();
Activity wf = new Sequence
{
Variables = { Operand1, Operand2, Result },
Activities =
{
new Add(),
new WriteLine
{
Text = new InArgument<string>(env => "The result is " + Result.Get(env))
}
}
};
Этот рабочий процесс можно проверить путем вызова Validate. Validate возвращает коллекцию любых ошибок валидации или предупреждений, содержащихся в действии и в его дочерних элементах, как показано в следующем примере.
ValidationResults results = ActivityValidationServices.Validate(wf);
if (results.Errors.Count == 0 && results.Warnings.Count == 0)
{
Console.WriteLine("No warnings or errors");
}
else
{
foreach (ValidationError error in results.Errors)
{
Console.WriteLine("Error: {0}", error.Message);
}
foreach (ValidationError warning in results.Warnings)
{
Console.WriteLine("Warning: {0}", warning.Message);
}
}
При Validate вызове этого примера рабочего процесса возвращаются две ошибки проверки.
Ошибка. Значение для требуемого аргумента действия "Операнд2" не было предоставлено.Ошибка. Значение для требуемого аргумента действия "Операнд1" не было предоставлено. Если этот рабочий процесс был вызван, InvalidWorkflowException создается исключение, как показано в следующем примере.
try
{
WorkflowInvoker.Invoke(wf);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
System.Activity.InvalidWorkflowException:При обработке дерева рабочего процесса обнаружены следующие ошибки:'Add': Значение для аргумента действия "Операнда2" не было предоставлено."Add": значение для требуемого аргумента действия "Операнд1" не было предоставлено. Чтобы этот пример рабочего процесса был допустимым, необходимо привязать два обязательных аргумента Add действия. В следующем примере два обязательных аргумента привязаны к переменным рабочего процесса вместе со значением результата. В этом примере аргумент Result связан вместе с двумя обязательными аргументами. Аргумент Result не является обязательным для привязки и не вызывает ошибку проверки, если это не так. Автор рабочего процесса несет ответственность за привязку Result , если его значение используется в другом месте рабочего процесса.
new Add
{
Operand1 = Operand1,
Operand2 = Operand2,
Result = Result
}
Проверка обязательных аргументов в корневом действии
Если корневое действие рабочего процесса имеет аргументы, они не привязываются, пока не вызывается рабочий процесс и не передаются параметры. Следующий рабочий процесс проходит проверку, но исключение возникает, если рабочий процесс вызывается без передачи необходимых аргументов, как показано в следующем примере.
Activity wf = new Add();
ValidationResults results = ActivityValidationServices.Validate(wf);
// results has no errors or warnings, but when the workflow
// is invoked, an InvalidWorkflowException is thrown.
try
{
WorkflowInvoker.Invoke(wf);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
System.ArgumentException: неправильные параметры аргумента корневого действия.Исправьте определение рабочего процесса или укажите входные значения для устранения этих ошибок:'Add': значение для требуемого аргумента действия "Операнд2" не было предоставлено."Add": значение для требуемого аргумента действия "Операнд1" не было предоставлено. После прохождения правильных аргументов рабочий процесс успешно завершается, как показано в следующем примере.
Add wf = new Add();
ValidationResults results = ActivityValidationServices.Validate(wf);
// results has no errors or warnings, and the workflow completes
// successfully because the required arguments were passed.
try
{
Dictionary<string, object> wfparams = new Dictionary<string, object>
{
{ "Operand1", 10 },
{ "Operand2", 15 }
};
int result = WorkflowInvoker.Invoke(wf, wfparams);
Console.WriteLine("Result: {0}", result);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Замечание
В этом примере корневое действие было объявлено как Add вместо Activity, как это было в предыдущем примере. Это позволяет WorkflowInvoker.Invoke методу возвращать одно целое число, представляющее результаты Add действия вместо словаря out аргументов. Переменная wf также может быть объявлена как Activity<int>.
При проверке корневых аргументов хостовое приложение должно обеспечить, чтобы все необходимые аргументы передавались при вызове рабочего процесса.
Вызов императивной проверки на основе кода
Императивная проверка на основе кода предоставляет простой способ для выполнения проверки самого действия и доступен для действий, производных от CodeActivity, AsyncCodeActivityи NativeActivity. Код проверки, определяющий любые ошибки проверки или предупреждения, добавляется в активность. При вызове валидизации действия эти предупреждения или ошибки содержатся в коллекции, возвращаемой вызовом Validate. В следующем примере CreateProduct определяется действие. Если Cost больше Price, то ошибка проверки добавляется в метаданные при переопределении CacheMetadata.
public sealed class CreateProduct : CodeActivity
{
public double Price { get; set; }
public double Cost { get; set; }
// [RequiredArgument] attribute will generate a validation error
// if the Description argument is not set.
[RequiredArgument]
public InArgument<string> Description { get; set; }
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
// Determine when the activity has been configured in an invalid way.
if (this.Cost > this.Price)
{
// Add a validation error with a custom message.
metadata.AddValidationError("The Cost must be less than or equal to the Price.");
}
}
protected override void Execute(CodeActivityContext context)
{
// Not needed for the sample.
}
}
В этом примере рабочий процесс настраивается с помощью CreateProduct действия. В этом рабочем процессе Cost больше, чем Price, и обязательный аргумент Description не установлен. При вызове проверки возвращаются следующие ошибки.
Activity wf = new Sequence
{
Activities =
{
new CreateProduct
{
Cost = 75.00,
Price = 55.00
// Cost > Price and required Description argument not set.
},
new WriteLine
{
Text = "Product added."
}
}
};
ValidationResults results = ActivityValidationServices.Validate(wf);
if (results.Errors.Count == 0 && results.Warnings.Count == 0)
{
Console.WriteLine("No warnings or errors");
}
else
{
foreach (ValidationError error in results.Errors)
{
Console.WriteLine("Error: {0}", error.Message);
}
foreach (ValidationError warning in results.Warnings)
{
Console.WriteLine("Warning: {0}", warning.Message);
}
}
Ошибка. Стоимость должна быть меньше или равна цене.Ошибка. Значение для обязательного аргумента действия "Описание" не было предоставлено.
Замечание
Авторы пользовательских действий могут предоставлять логику проверки в переопределении действия CacheMetadata . Исключения, генерируемые из CacheMetadata, не рассматриваются как ошибки проверки. Эти исключения будут выходить из вызова Validate и должны обрабатываться вызывающей стороной.
Использование ValidationSettings
По умолчанию все действия в дереве действий оцениваются при вызове ActivityValidationServicesпроверки.
ValidationSettings позволяет настроить проверку различными способами, настроив три его свойства.
SingleLevel указывает, должен ли проверяющий ходить по всему дереву действий или применять логику проверки только к предоставленному действию. Значение по умолчанию для этого значения равно false.
AdditionalConstraints задает дополнительное сопоставление ограничений от типа к списку ограничений. Для базового типа каждой активности в дереве активности выполняется поиск в AdditionalConstraints. Если найден соответствующий список ограничений, все ограничения в списке оцениваются для действия.
OnlyUseAdditionalConstraints указывает, должен ли проверяющий оценивать все ограничения или только те, которые указаны в AdditionalConstraints. Значение по умолчанию — false.
AdditionalConstraints и OnlyUseAdditionalConstraints полезны для авторов хостов рабочих процессов, чтобы добавить дополнительную проверку для рабочих процессов, таких как политические ограничения для таких инструментов, как FxCop. Дополнительные сведения об ограничениях см. в разделе "Декларативные ограничения".
Чтобы использовать ValidationSettings, настройте требуемые свойства и передайте его в вызов Validate. В этом примере проверяется рабочий процесс, который состоит из Sequence с пользовательской Add активностью. Действие Add имеет два обязательных аргумента.
public sealed class Add : CodeActivity<int>
{
[RequiredArgument]
public InArgument<int> Operand1 { get; set; }
[RequiredArgument]
public InArgument<int> Operand2 { get; set; }
protected override int Execute(CodeActivityContext context)
{
return Operand1.Get(context) + Operand2.Get(context);
}
}
Add Следующее действие используется в объектеSequence, но два обязательных аргумента не привязаны.
Variable<int> Operand1 = new Variable<int> { Default = 10 };
Variable<int> Operand2 = new Variable<int> { Default = 15 };
Variable<int> Result = new Variable<int>();
Activity wf = new Sequence
{
Variables = { Operand1, Operand2, Result },
Activities =
{
new Add(),
new WriteLine
{
Text = new InArgument<string>(env => "The result is " + Result.Get(env))
}
}
};
В следующем примере проверка выполняется с SingleLevel, установленным в true, поэтому проверяется только корневая Sequence активность.
ValidationSettings settings = new ValidationSettings
{
SingleLevel = true
};
ValidationResults results = ActivityValidationServices.Validate(wf, settings);
if (results.Errors.Count == 0 && results.Warnings.Count == 0)
{
Console.WriteLine("No warnings or errors");
}
else
{
foreach (ValidationError error in results.Errors)
{
Console.WriteLine("Error: {0}", error.Message);
}
foreach (ValidationError warning in results.Warnings)
{
Console.WriteLine("Warning: {0}", warning.Message);
}
}
В этом коде отображаются следующие выходные данные:
Нет предупреждений или ошибок Несмотря на то, что действие Add имеет обязательные аргументы, которые не привязаны, проверка выполняется успешно, так как вычисляется только корневое действие. Этот тип проверки полезен для проверки только определенных элементов в дереве действий, таких как проверка изменения свойства одного действия в конструкторе. Обратите внимание, что если этот рабочий процесс вызывается, выполняется полная проверка, настроенная в рабочем процессе, и InvalidWorkflowException будет выброшено исключение.
ActivityValidationServices и ValidationSettings настройте только проверку, явно вызываемую узлом, а не проверку, которая возникает при вызове рабочего процесса.