通过


了解执行上下文

事件执行管道传递已注册的插件,其中提供了大量有关正在处理的当前操作和自定义代码的执行环境的数据。 以下部分描述传递到插件或自定义工作流活动的数据。

访问插件的执行上下文

使用插件,通过设置实现接口的 IPluginExecutionContext 变量来访问代码中的此数据:

// Obtain the execution context from the service provider.  
IPluginExecutionContext context = (IPluginExecutionContext)
    serviceProvider.GetService(typeof(IPluginExecutionContext));

IPluginExecutionContext 提供有关插件注册对象Stage的一些信息,以及有关ParentContext的信息。

详细信息: ParentContext

访问自定义工作流活动的执行上下文

使用自定义工作流活动,通过设置实现接口的 IWorkflowContext 变量来访问代码中的此数据:

// Obtain the execution context using the GetExtension method.  
protected override void Execute(CodeActivityContext context)
{
 IWorkflowContext workflowContext = context.GetExtension<IWorkflowContext>();
...

IWorkflowContext 提供了有关自定义工作流活动在其中运行的工作流的一些信息。

财产 说明
ParentContext 获取父上下文。 请参阅 ParentContext
StageName 获取进程实例的阶段信息。
WorkflowCategory 获取进程实例的进程类别信息:它是工作流或对话(已弃用)。
WorkflowMode 指示工作流的执行方式。 0 = 异步,1 = 同步

ParentContext

ParentContext 提供有关触发插件或自定义工作流活动运行的任何操作的信息。

除特定已记录的情况外,请避免依赖 ParentContext 中找到的值来应用您的业务逻辑。 无法保证操作发生的特定顺序,并且可能会随时间而变化。

如果您选择依赖于ParentContext中找到的值,请采取措施确保您的代码具有弹性,以适应潜在的更改。 定期测试逻辑,以验证所依赖的条件在一段时间内是否保持有效。

执行上下文

IExecutionContext 接口提供其余信息。 IPluginExecutionContext类和IWorkflowContext类实现此接口。

对于插件,此执行上下文类的所有属性都提供了在代码中可能需要访问的有用信息。

注释

对于自定义工作流活动,通常不会使用这些属性。

最重要的两个属性是 InputParameters 属性和 OutputParameters 属性。

其他常用属性是 SharedVariablesPreEntityImages以及 PostEntityImages

小窍门

可视化传入执行上下文的数据的好方法是安装作为插件注册工具一部分提供的插件探查器解决方案。 分析器会捕获上下文信息以及用于本地重放事件的信息,以便您进行调试。 在插件注册工具中,可以从触发工作流的事件下载包含所有数据的 XML 文档。 有关详细信息,请参阅 “查看插件配置文件数据”。

参数集合

执行上下文的所有属性都是只读的。 InputParameters但是,OutputParametersSharedVariablesParameterCollection值。 可以通过修改这些集合中项的值来更改操作的行为,具体取决于插件注册的事件执行管道中的阶段。

这些 ParameterCollection 值定义为 KeyValuePair 结构。 若要访问属性,需要知道消息公开的属性的名称。 例如,若要访问作为CreateRequest一部分传递的Entity属性,需要知道该属性的名称是Target。 然后,可以使用如下所示的代码来访问此值:

var entity = (Entity)context.InputParameters["Target"];

使用Microsoft.Xrm.Sdk.MessagesMicrosoft.Crm.Sdk.Messages文档来了解 SDK 程序集中定义的消息名称。 有关自定义操作,请参阅系统中定义的参数的名称。

输入参数

InputParameters 表示来自 Web 服务的操作的 OrganizationRequestParameters 属性的值。

使用 .NET 的 SDK 消息中所述,系统中发生的所有操作最终都是由 IOrganizationServiceExecute 方法处理的 OrganizationRequest 类的实例。

事件框架中所述,操作将经历一系列阶段。 可以在将数据写入数据库之前发生的阶段注册插件。 在 PreValidationPreOperation 阶段中,可以读取和更改值 InputParameters ,以便可以控制数据操作的预期结果。

如果发现 InputParameters 集合中的值表示某个条件不允许,请引发一个 InvalidPluginExecutionException (最好在 PreValidation 阶段),取消该操作。如果使用同步插件,错误将显示给用户;如果插件是异步的,则会记录错误。 有关详细信息,请参阅 “取消操作”。

输出参数

OutputParameters 表示 OrganizationResponse.Results 属性的值,该属性代表操作的返回值。 每个派生自 OrganizationResponse 的消息响应类包含特定属性。 若要访问这些属性,请使用键值 ,该值通常 与响应类中的属性的名称相同。 但是,这并不总是如此。 下表列出了消息响应类属性,这些属性具有不同于属性名称的键。

响应类 财产 键值
BackgroundSendEmailResponse EntityCollection BusinessEntityCollection
CloneContractResponse Entity BusinessEntity
CloneMobileOfflineProfileResponse CloneMobileOfflineProfile EntityReference
CloneProductResponse ClonedProduct EntityReference
ConvertSalesOrderToInvoiceResponse Entity BusinessEntity
CreateKnowledgeArticleTranslationResponse CreateKnowledgeArticleTranslation EntityReference
CreateKnowledgeArticleVersionResponse CreateKnowledgeArticleVersion EntityReference
GenerateQuoteFromOpportunityResponse Entity BusinessEntity
GetDefaultPriceLevelResponse PriceLevels BusinessEntityCollection
RetrieveResponse Entity BusinessEntity
RetrieveMultipleResponse EntityCollection BusinessEntityCollection
RetrievePersonalWallResponse EntityCollection BusinessEntityCollection
RetrieveRecordWallResponse EntityCollection BusinessEntityCollection
RetrieveUnpublishedResponse Entity BusinessEntity
RetrieveUnpublishedMultipleResponse EntityCollection BusinessEntityCollection
RetrieveUserQueuesResponse EntityCollection BusinessEntityCollection

系统在数据库事务完成后才填充OutputParameters,因此只有注册在PostOperation阶段的插件才能使用它们。 如果要更改操作返回的值,可以在其中 OutputParameters修改它们。

共享变量

使用 SharedVariables 属性将数据从 API 或插件传递到执行管道稍后发生的步骤。 由于此属性是一个 ParameterCollection 值,因此插件可以添加、读取或修改属性,以便通过后续步骤共享数据。

以下示例演示了如何将 PrimaryContact 值从注册在 PreOperation 步骤的插件传递给 PostOperation 步骤。

public class PreOperation : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        // Obtain the execution context from the service provider.
        Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
            serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

        // Create or retrieve some data that will be needed by the post event
        // plug-in. You could run a query, create an entity, or perform a calculation.
        //In this sample, the data to be passed to the post plug-in is
        // represented by a GUID.
        Guid contact = new Guid("{74882D5C-381A-4863-A5B9-B8604615C2D0}");

        // Pass the data to the post event plug-in in an execution context shared
        // variable named PrimaryContact.
        context.SharedVariables.Add("PrimaryContact", (Object)contact.ToString());
    }
}

public class PostOperation : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        // Obtain the execution context from the service provider.
        Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
            serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

        // Obtain the contact from the execution context shared variables.
        if (context.SharedVariables.Contains("PrimaryContact"))
        {
            Guid contact =
                new Guid((string)context.SharedVariables["PrimaryContact"]);

            // Do something with the contact.
        }
    }
}

重要

必须将可序列化的数据添加到共享变量集合。 否则,服务器不知道如何序列化数据和插件执行失败。

注释

对于注册在 PreOperationPostOperation 阶段的插件,若要访问注册在 PreValidation 阶段(该阶段在创建更新删除阶段,或由 RetrieveExchangeRateRequest 执行),您必须访问 ParentContext.SharedVariables 集合。 对于所有其他情况, IPluginExecutionContextSharedVariables 包含集合。

从 API 传递共享变量

若要在调用 API 时引入共享变量,请使用 Web API 或用于 .NET 的 SDK 中的关键字 tag 传递字符串值。

可以使用键访问共享变量集合 tag 中的此值。 设置后,无法更改此值。

有关详细信息,请参阅 向插件执行上下文添加共享变量

实体图像

当您为包含表作为参数之一的插件注册步骤时,可以使用 PreEntityImagesPostEntityImages 属性指定将表数据的副本作为快照或映像包含在内。

此数据为表数据在流经事件管道时提供比较点。 使用这些图像可提供更好的性能,而不是在插件中包含代码来检索表,只是为了比较属性值。

定义实体映像时,可以指定可用于访问特定映像的实体别名值。 例如,如果使用别名“”a定义实体前图像,则可以使用以下代码访问 name 属性值。

var oldAccountName = (string)context.PreEntityImages["a"]["name"];

详细信息:

另见

事件框架
编写插件