Delen via


Validatie van activiteit aanroepen

Activiteitsvalidatie biedt een methode voor het identificeren en rapporteren van fouten in de configuratie van een activiteit voordat deze wordt uitgevoerd. Validatie vindt plaats wanneer een werkstroom wordt gewijzigd in de werkstroomontwerper en eventuele validatiefouten of waarschuwingen worden weergegeven in de werkstroomontwerper. Validatie vindt ook plaats tijdens runtime wanneer een werkstroom wordt aangeroepen en als er validatiefouten optreden, wordt er een InvalidWorkflowException gegenereerd door de standaardvalidatielogica. Windows Workflow Foundation (WF) biedt de ActivityValidationServices klasse die kan worden gebruikt door werkstroomtoepassings- en hulpprogrammaontwikkelaars om expliciet een activiteit te valideren. In dit onderwerp wordt beschreven hoe u ActivityValidationServices activiteitsvalidatie uitvoert.

ActivityValidationServices gebruiken

ActivityValidationServices heeft twee Validate overbelastingen die worden gebruikt om de validatielogica van een activiteit aan te roepen. Bij de eerste overbelasting wordt de hoofdactiviteit gevalideerd en wordt een verzameling validatiefouten en waarschuwingen geretourneerd. In het volgende voorbeeld wordt een aangepaste Add activiteit gebruikt met twee vereiste argumenten.

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);  
    }  
}  

De Add activiteit wordt gebruikt in een Sequence, maar de twee vereiste argumenten zijn niet gebonden, zoals wordt weergegeven in het volgende voorbeeld.

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))  
        }  
    }  
};  

Deze werkstroom kan worden gevalideerd door aan te roepen Validate. Validate retourneert een verzameling validatiefouten of waarschuwingen die zijn opgenomen in de activiteit en eventuele onderliggende items, zoals wordt weergegeven in het volgende voorbeeld.

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);  
    }  
}  

Wanneer Validate deze voorbeeldwerkstroom wordt aangeroepen, worden er twee validatiefouten geretourneerd.

Fout: de waarde voor een vereist activiteitsargument 'Operand2' is niet opgegeven.
Fout: de waarde voor een vereist activiteitsargument 'Operand1' is niet opgegeven. Als deze werkstroom is aangeroepen, wordt er een InvalidWorkflowException gegenereerd, zoals wordt weergegeven in het volgende voorbeeld.

try  
{  
    WorkflowInvoker.Invoke(wf);  
}  
catch (Exception ex)  
{  
    Console.WriteLine(ex);  
}  

System.Activities.InvalidWorkflowException:
De volgende fouten zijn opgetreden tijdens het verwerken van de werkstroomstructuur: 'Toevoegen': Waarde voor een vereist activiteitsargument 'Operand2' is niet opgegeven.' Toevoegen': De waarde voor een vereist activiteitsargument 'Operand1' is niet opgegeven. Om deze voorbeeldwerkstroom geldig te maken, moeten de twee vereiste argumenten van de Add activiteit afhankelijk zijn. In het volgende voorbeeld zijn de twee vereiste argumenten gekoppeld aan werkstroomvariabelen, samen met de resultaatwaarde. In dit voorbeeld is het Result argument afhankelijk van de twee vereiste argumenten. Het Result argument hoeft niet gebonden te zijn en veroorzaakt geen validatiefout als dat niet het geval is. Het is de verantwoordelijkheid van de auteur van de werkstroom om te binden Result als de waarde ergens anders in de werkstroom wordt gebruikt.

new Add  
{  
    Operand1 = Operand1,  
    Operand2 = Operand2,  
    Result = Result  
}  

Vereiste argumenten voor de hoofdactiviteit valideren

Als de hoofdactiviteit van een werkstroom argumenten heeft, zijn deze pas afhankelijk als de werkstroom wordt aangeroepen en parameters worden doorgegeven aan de werkstroom. De volgende werkstroom wordt gevalideerd, maar er wordt een uitzondering gegenereerd als de werkstroom wordt aangeroepen zonder de vereiste argumenten door te geven, zoals wordt weergegeven in het volgende voorbeeld.

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: de argumentinstellingen van de hoofdactiviteit zijn onjuist.
Corrigeer de werkstroomdefinitie of geef invoerwaarden op om deze fouten op te lossen: 'Toevoegen': Waarde voor een vereist activiteitsargument 'Operand2' is niet opgegeven.' Toevoegen': De waarde voor een vereist activiteitsargument 'Operand1' is niet opgegeven. Nadat de juiste argumenten zijn doorgegeven, wordt de werkstroom voltooid, zoals wordt weergegeven in het volgende voorbeeld.

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);  
}  

Notitie

In dit voorbeeld is de hoofdactiviteit gedeclareerd als Add in plaats van Activity in het vorige voorbeeld. Hierdoor kan de WorkflowInvoker.Invoke methode één geheel getal retourneren dat de resultaten van de Add activiteit vertegenwoordigt in plaats van een woordenlijst met out argumenten. De variabele wf kan ook zijn gedeclareerd als Activity<int>.

Bij het valideren van hoofdargumenten is het de verantwoordelijkheid van de hosttoepassing om ervoor te zorgen dat alle vereiste argumenten worden doorgegeven wanneer de werkstroom wordt aangeroepen.

Validatie op basis van imperatieve code aanroepen

Imperatieve op code gebaseerde validatie biedt een eenvoudige manier voor een activiteit om validatie over zichzelf te bieden en is beschikbaar voor activiteiten die zijn afgeleid van CodeActivity, AsyncCodeActivityen NativeActivity. Validatiecode waarmee eventuele validatiefouten of waarschuwingen worden bepaald, wordt toegevoegd aan de activiteit. Wanneer de validatie wordt aangeroepen voor de activiteit, worden deze waarschuwingen of fouten opgenomen in de verzameling die wordt geretourneerd door de aanroep naar Validate. In het volgende voorbeeld wordt een CreateProduct activiteit gedefinieerd. Als de waarde Cost groter is dan de Pricewaarde, wordt er een validatiefout toegevoegd aan de metagegevens in de CacheMetadata onderdrukking.

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.  
    }  
}  

In dit voorbeeld wordt een werkstroom geconfigureerd met behulp van de CreateProduct activiteit. In deze werkstroom is de Cost waarde groter dan de Priceen het vereiste Description argument niet ingesteld. Wanneer validatie wordt aangeroepen, worden de volgende fouten geretourneerd.

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);  
    }  
}  

Fout: De kosten moeten kleiner zijn dan of gelijk zijn aan de prijs.
Fout: de waarde voor een vereist activiteitsargument 'Beschrijving' is niet opgegeven.

Notitie

Auteurs van aangepaste activiteiten kunnen validatielogica bieden in de onderdrukking van CacheMetadata een activiteit. Eventuele uitzonderingen die worden gegenereerd CacheMetadata , worden niet behandeld als validatiefouten. Deze uitzonderingen ontsnappen van de aanroep naar Validate en moeten worden verwerkt door de beller.

Validatie gebruiken Instellingen

Standaard worden alle activiteiten in de activiteitenstructuur geëvalueerd wanneer de validatie wordt aangeroepen door ActivityValidationServices. ValidationSettings hiermee kan de validatie op verschillende manieren worden aangepast door de drie eigenschappen ervan te configureren. SingleLevel geeft aan of de validator de hele activiteitenstructuur moet doorlopen of alleen validatielogica moet toepassen op de opgegeven activiteit. De standaardwaarde voor deze waarde is false. AdditionalConstraints hiermee geeft u aanvullende beperkingstoewijzing van een type naar een lijst met beperkingen. Voor het basistype van elke activiteit in de activiteitsstructuur die wordt gevalideerd, wordt er een zoekactie uitgevoerd AdditionalConstraints. Als er een overeenkomende beperkingslijst wordt gevonden, worden alle beperkingen in de lijst geëvalueerd voor de activiteit. OnlyUseAdditionalConstraints geeft aan of de validator alle beperkingen moet evalueren of alleen de beperkingen die zijn opgegeven in AdditionalConstraints. De standaardwaarde is false. AdditionalConstraints en OnlyUseAdditionalConstraints zijn nuttig voor auteurs van werkstroomhosts om extra validatie toe te voegen voor werkstromen, zoals beleidsbeperkingen voor hulpprogramma's zoals FxCop. Zie declaratieve beperkingen voor meer informatie over beperkingen.

Als u wilt gebruiken ValidationSettings, configureert u de gewenste eigenschappen en geeft u deze vervolgens door in de aanroep naar Validate. In dit voorbeeld wordt een werkstroom die bestaat uit een Sequence met een aangepaste Add activiteit gevalideerd. De Add activiteit heeft twee vereiste argumenten.

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);  
    }  
}  

De volgende Add activiteit wordt gebruikt in een Sequence, maar de twee vereiste argumenten zijn niet gebonden.

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))  
        }  
    }  
};  

In het volgende voorbeeld wordt validatie uitgevoerd met SingleLevel ingesteld op true, dus alleen de hoofdactiviteit Sequence wordt gevalideerd.

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);  
    }  
}  

Met deze code wordt de volgende uitvoer weergegeven:

Geen waarschuwingen of fouten Hoewel de activiteit vereiste argumenten heeft die niet zijn gebonden, is de Add validatie geslaagd omdat alleen de hoofdactiviteit wordt geëvalueerd. Dit type validatie is handig voor het valideren van alleen specifieke elementen in een activiteitsstructuur, zoals het valideren van een eigenschapswijziging van één activiteit in een ontwerper. Als deze werkstroom wordt aangeroepen, wordt de volledige validatie die is geconfigureerd in de werkstroom geëvalueerd en wordt er een InvalidWorkflowException gegenereerd. ActivityValidationServices en ValidationSettings configureer alleen validatie die expliciet door de host wordt aangeroepen, en niet de validatie die optreedt wanneer een werkstroom wordt aangeroepen.