Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Este tema es aplicable a Windows Workflow Foundation 4.
La validación de la actividad proporciona un método para identificar y notificar los errores en la configuración de cualquier actividad antes de su ejecución. La validación se produce cuando un flujo de trabajo se modifica en el diseñador de flujo de trabajo y cuando los errores de validación o advertencias se muestran en el diseñador de flujo de trabajo. La validación también se produce en el tiempo de ejecución cuando se invoca un flujo de trabajo y, si se produce un error de validación, la lógica de validación predeterminada inicia InvalidWorkflowException. Windows Workflow Foundation (WF) proporciona la clase ActivityValidationServices que los desarrolladores de herramientas y de la aplicación de flujo de trabajo pueden usar para validar una actividad explícitamente. En este tema se describe cómo usar ActivityValidationServices para realizar la validación de actividad.
Usar ActivityValidationServices
ActivityValidationServices tiene dos sobrecargas de Validate que se usan para invocar la lógica de validación de una actividad. La primera sobrecarga toma la actividad raíz que se va a validar y devuelve una colección de errores de validación y advertencias. En el siguiente ejemplo, se usa una actividad Add
personalizada que tiene dos argumentos necesarios.
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);
}
}
La actividad Add
se usa dentro de Sequence, aunque no se enlazan sus dos argumentos necesarios, tal y como se muestra en el siguiente ejemplo.
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 flujo de trabajo se puede validar llamando a Validate. Validate devuelve una colección de errores de validación o advertencias contenidas por la actividad y cualquier elemento secundario, tal y como se muestra en el siguiente ejemplo.
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);
}
}
![]() |
---|
Los autores de actividades personalizadas pueden proporcionar lógica de validación en la invalidación del método CacheMetadata de una actividad. Cualquier excepción que se produzca desde el método CacheMetadata no se trata como errores de validación. Estas excepciones escaparán de la llamada al método Validate y serán administradas por el autor de la llamada. |
Cuando se llama a Validate en este flujo de trabajo de ejemplo, se devuelven dos errores de validación.
Error: Value for a required activity argument 'Operand2' was not supplied.
Error: Value for a required activity argument 'Operand1' was not supplied.
Si se invocara este flujo de trabajo, se produciría una excepción InvalidWorkflowException, tal y como se muestra en el siguiente ejemplo.
try
{
WorkflowInvoker.Invoke(wf);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
System.Activities.InvalidWorkflowException:
The following errors were encountered while processing the workflow tree:
'Add': Value for a required activity argument 'Operand2' was not supplied.
'Add': Value for a required activity argument 'Operand1' was not supplied.
Para que este flujo de trabajo de ejemplo sea válido, se deben enlazar los dos argumentos necesarios de la actividad Add
. En el siguiente ejemplo, los dos argumentos necesarios se enlazan con las variables de flujo de trabajo junto con el valor de resultado. En este ejemplo, el argumento Result se enlaza con los dos argumentos necesarios. No se exige que se enlace el argumento Result y no provoca un error de validación si no lo está. Es responsabilidad del autor del flujo de trabajo enlazar Result si su valor se usa en otra parte en el flujo de trabajo.
new Add
{
Operand1 = Operand1,
Operand2 = Operand2,
Result = Result
}
Validación de argumentos necesarios en la actividad raíz
Si la actividad raíz de un flujo de trabajo tiene argumentos, no se enlazarán hasta que se invoque el flujo de trabajo y los parámetros pasen al flujo de trabajo, de modo que el siguiente flujo de trabajo pase la validación aunque se producirá una excepción si el flujo de trabajo se invocó sin pasar los argumentos necesarios, tal y como se muestra en el siguiente ejemplo.
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: The root activity's argument settings are incorrect.
Either fix the workflow definition or supply input values to fix these errors:
'Add': Value for a required activity argument 'Operand2' was not supplied.
'Add': Value for a required activity argument 'Operand1' was not supplied.
Una vez pasados los argumentos correctos, el flujo de trabajo se completa correctamente, tal y como se muestra en el siguiente ejemplo.
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);
}
![]() |
---|
En este ejemplo, la actividad raíz se declaró como Add en lugar de Activity, tal y como se especificó en el ejemplo anterior. Esto permite al método WorkflowInvoker.Invoke devolver un entero único que representa los resultados de la actividad Add en lugar de un diccionario de argumentos out. La variable wf también se puede declarar como Activity<int> .
|
Al validar los argumentos raíz, la responsabilidad de la aplicación host es asegurarse de que se pasan todos los argumentos necesarios cuando se invoca el flujo de trabajo.
Usar ValidationSettings
De forma predeterminada, se evalúan todas las actividades en el árbol de actividad cuando ActivityValidationServices invoca la validación. ValidationSettings permite personalizar la validación de varias maneras diferentes configurando sus tres propiedades. SingleLevel especifica si el validador debería recorrer el árbol de actividad completo o sólo aplicar la lógica de validación a la actividad proporcionada. El valor predeterminado para este valor es false. AdditionalConstraints especifica la asignación de restricción adicional de un tipo a una lista de restricciones. Para el tipo base de cada actividad en el árbol de actividad que se esté validando, hay una búsqueda en AdditionalConstraints. Si se encuentra una lista de restricciones que coincida, todas las restricciones de la lista se evalúan para la actividad. OnlyUseAdditionalConstraints especifica si el validador debería evaluar todas las restricciones o sólo aquéllas especificadas en AdditionalConstraints. El valor predeterminado es false. AdditionalConstraints y OnlyUseAdditionalConstraints son útiles para que los autores de host de flujo de trabajo agreguen la validación adicional a los flujos de trabajo, por ejemplo, las restricciones de directivas para herramientas como FxCop. Para obtener más información sobre las restricciones, vea Restricciones declarativas.
Para usar ValidationSettings, configure las propiedades que desee y, a continuación, páselo en la llamada a Validate. En este ejemplo, se valida un flujo de trabajo que está compuesto de un Sequence con una actividad Add
personalizada. La actividad Add
tiene dos argumentos necesarios.
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);
}
}
La siguiente actividad Add
se usa en Sequence, pero no se enlazan sus dos argumentos necesarios.
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))
}
}
};
En el ejemplo siguiente, la validación se realiza con la propiedad SingleLevel definida en true, por lo que sólo se valida la actividad raíz 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);
}
}
Este código muestra el siguiente resultado.
Ninguna advertencia o error
Aunque la actividad Add
haya exigido argumentos que no están enlazados, la validación será correcta porque sólo se evaluó la actividad raíz. Este tipo de validación es útil sólo para validar los elementos concretos en un árbol de actividad, como la validación de un cambio de propiedad de una actividad única en un diseñador. Tenga en cuenta que si se invocara este flujo de trabajo, se evaluaría la validación completa configurada en el flujo de trabajo y se produciría una excepción InvalidWorkflowException. ActivityValidationServices y ValidationSettings sólo configuran explícitamente la validación invocada por el host y no la validación que se produce cuando se invoca un flujo de trabajo.