Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
A validação de atividades fornece um método para identificar e reportar erros na configuração de qualquer atividade antes da sua execução. A validação ocorre quando um fluxo de trabalho é modificado no designer do workflow e quaisquer erros ou avisos de validação são exibidos no designer do workflow. A validação também ocorre em tempo de execução, quando um fluxo de trabalho é invocado e, se ocorrerem erros de validação, um InvalidWorkflowException é lançado pela lógica de validação padrão. O Windows Workflow Foundation (WF) fornece a ActivityValidationServices classe que pode ser usada por programadores de aplicações e ferramentas de workflow para validar explicitamente uma atividade. Este tópico descreve como usar ActivityValidationServices para realizar validação de atividades.
Uso do ActivityValidationServices
ActivityValidationServices tem duas Validate sobrecargas que são usadas para invocar a lógica de validação de uma atividade. A primeira sobrecarga leva a atividade raiz a ser validada e devolve uma coleção de erros e avisos de validação. No exemplo seguinte, é usada uma atividade personalizada Add que tem dois argumentos obrigatórios.
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);
}
}
A Add atividade é usada dentro de um Sequence, mas os seus dois argumentos necessários não são limitados, como mostrado no exemplo seguinte.
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))
}
}
};
Este fluxo de trabalho pode ser validado chamando Validate. Validate devolve uma coleção de quaisquer erros de validação ou avisos contidos pela atividade e por quaisquer filhos, como mostrado no exemplo seguinte.
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);
}
}
Quando Validate é chamado neste fluxo de trabalho de exemplo, são devolvidos dois erros de validação.
Erro: O valor para um argumento de atividade requerida 'Operand2' não foi fornecido.Erro: O valor para o argumento de atividade requerida 'Operand1' não foi fornecido. Se este fluxo de trabalho fosse invocado, um InvalidWorkflowException seria lançado, como mostrado no exemplo seguinte.
try
{
WorkflowInvoker.Invoke(wf);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
System.Activities.InvalidWorkflowException:Os seguintes erros foram encontrados durante o processamento da árvore de workflow:'Add': O valor para um argumento de atividade requerida 'Operand2' não foi fornecido.'Add': Valor para um argumento de atividade requerida 'Operand1' não foi fornecido. Para que este fluxo de trabalho de exemplo seja válido, os dois argumentos necessários da Add atividade devem estar vinculados. No exemplo seguinte, os dois argumentos necessários estão ligados a variáveis de fluxo de trabalho juntamente com o valor do resultado. Neste exemplo, o Result argumento é vinculado juntamente com os dois argumentos necessários. O Result argumento não é obrigado a ser vinculado e não causa erro de validação se não for. É responsabilidade do autor do fluxo de trabalho vincular Result se o seu valor for usado noutro local do fluxo.
new Add
{
Operand1 = Operand1,
Operand2 = Operand2,
Result = Result
}
Validação dos argumentos necessários sobre a atividade raiz
Se a atividade raiz de um fluxo de trabalho tiver argumentos, estes não são limitados até que o fluxo de trabalho seja invocado e os parâmetros sejam passados ao fluxo. O fluxo de trabalho seguinte passa validação, mas uma exceção é lançada se o fluxo de trabalho for invocado sem passar os argumentos necessários, como mostrado no exemplo seguinte.
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: As definições de argumento da atividade raiz estão incorretas.Ou corrigir a definição do fluxo de trabalho ou fornecer valores de entrada para corrigir estes erros:'Add': Valor para um argumento de atividade requerida 'Operand2' não foi fornecido.'Add': Valor para um argumento de atividade requerida 'Operand1' não foi fornecido. Após a passagem dos argumentos corretos, o fluxo de trabalho é concluído com sucesso, como mostrado no exemplo seguinte.
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);
}
Observação
Neste exemplo, a atividade raiz foi declarada como Add em vez de Activity como no exemplo anterior. Isto permite que o WorkflowInvoker.Invoke método devolva um único inteiro que representa os resultados da Add atividade em vez de um dicionário de out argumentos. A variável wf também poderia ter sido declarada como Activity<int>.
Ao validar argumentos raiz, é responsabilidade da aplicação anfitriã garantir que todos os argumentos necessários são aprovados quando o fluxo de trabalho é invocado.
Invocação de Validação Baseada em Código Imperativo
A validação imperativa baseada em código fornece uma forma simples de uma atividade fornecer validação sobre si própria, e está disponível para atividades que derivam de CodeActivity, AsyncCodeActivity, e NativeActivity. Código de validação que determina quaisquer erros ou avisos de validação é adicionado à atividade. Quando a validação é invocada na atividade, estes avisos ou erros ficam contidos na coleção devolvida pela chamada para Validate. No exemplo seguinte, uma CreateProduct atividade é definida. Se o Cost for maior que o Price, é adicionado um erro de validação aos metadados no CacheMetadata override.
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.
}
}
Neste exemplo, um fluxo de trabalho é configurado usando a CreateProduct atividade. Neste fluxo de trabalho, o Cost é maior que o Price, e o argumento necessário Description não está definido. Quando a validação é invocada, os seguintes erros são devolvidos.
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);
}
}
Erro: O Custo deve ser inferior ou igual ao Preço.Erro: Valor para um argumento de atividade requerida 'Description' não foi fornecido.
Observação
Os autores de atividades personalizadas podem fornecer lógica de validação na substituição de CacheMetadata de uma atividade. Quaisquer exceções que sejam lançadas por CacheMetadata não são tratadas como erros de validação. Essas exceções irão escapar da chamada para Validate e devem ser tratadas pelo chamador.
Utilização do ValidationSettings
Por defeito, todas as atividades na árvore de atividades são avaliadas quando a validação é invocada por ActivityValidationServices.
ValidationSettings permite que a validação seja personalizada de várias formas diferentes, configurando as suas três propriedades.
SingleLevel especifica se o validador deve percorrer toda a árvore de atividades ou apenas aplicar lógica de validação à atividade fornecida. O valor padrão para este valor é false.
AdditionalConstraints especifica o mapeamento adicional de restrições de um tipo para uma lista de restrições. Para cada tipo base de atividade na árvore de atividades que está a ser validada, realiza-se uma pesquisa em AdditionalConstraints. Se for encontrada uma lista de restrições correspondente, todas as restrições da lista são avaliadas para a atividade.
OnlyUseAdditionalConstraints especifica se o validador deve avaliar todas as restrições ou apenas aquelas especificadas em AdditionalConstraints. O valor predefinido é false.
AdditionalConstraints e OnlyUseAdditionalConstraints são úteis para autores de anfitriões de workflow adicionarem validação adicional para fluxos de trabalho, como restrições de políticas para ferramentas como o FxCop. Para mais informações sobre restrições, veja Restrições Declarativas.
Para usar ValidationSettings, configure as propriedades desejadas e depois passe-o na chamada para Validate. Neste exemplo, é validado um fluxo de trabalho que consiste em um Sequence com uma atividade personalizada Add. A Add atividade tem dois argumentos obrigatórios.
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);
}
}
A atividade seguinte Add é usada num Sequence, mas os seus dois argumentos obrigatórios não estão vinculados.
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))
}
}
};
No exemplo seguinte, a validação é realizada com SingleLevel definido como true, pelo que apenas a atividade raiz Sequence é validada.
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);
}
}
Este código exibe a seguinte saída:
Sem avisos ou erros Mesmo que a Add atividade tenha exigido argumentos que não estão vinculados, a validação é bem-sucedida porque apenas a atividade raiz é avaliada. Este tipo de validação é útil para validar apenas elementos específicos numa árvore de atividades, como a validação de uma alteração de propriedade de uma única atividade num designer. Note que, se este fluxo de trabalho for invocado, a validação completa configurada no fluxo de trabalho será avaliada e um InvalidWorkflowException será lançado.
ActivityValidationServices e ValidationSettings configurar apenas a validação explicitamente invocada pelo anfitrião, e não a validação que ocorre quando um fluxo de trabalho é invocado.