创建自己的行动
发布日期: 2017年1月
适用于: Dynamics 365 (online),Dynamics 365 (on-premises),Dynamics CRM 2016,Dynamics CRM Online
可以通过创建称为操作的自定义消息来扩展 Microsoft Dynamics 365 的功能。 这些操作将具有关联的请求/响应类,而且将生成 Web API 操作。 操作通常用于将新域特定的功能添加到组织 Web 服务,或者将多个组织 Web 服务消息请求合并到一个请求。 例如,在支持呼叫中心,您可能要将 Create、Assign 和 Setstate 消息合并为单个新 Escalate 消息。
操作的业务逻辑是使用工作流实现的。 当创建操作时,关联实时工作流自动注册以在执行管道的第 30 个阶段(核心操作)中执行。 有关实时工作流的详细信息,请参阅Dynamics 365 流程类别"。
虽然操作在两个 Microsoft Dynamics 365(在线或本地) 都受到支持,但是内部部署和 IFD 部署仅支持在代码中创建操作(使用 XAML)。 联机客户必须在 Web 应用程序中以交互方式创建操作。
在本主题中
关于操作定义
所需权限
使用代码创建操作
打包操作以进行分发
为操作生成早期绑定类型
使用 Web API 执行操作
使用组织服务执行操作
使用流程执行操作
监视长时间运行的操作
关于操作定义
与实时工作流类似,操作使用 Workflow 实体记录进行定义。 下表列出操作含义和工作原理的要点:
可以与单个实体或全局关联(不与任何特定实体关联)。
在事件执行管道的核心操作阶段 30 中执行。
支持调用在事件执行管道的前期操作和后期操作阶段注册的插件。
只有在活动状态为“激活”的情况下,才可以在前期操作和后期操作阶段注册插件。
在 organization.svc 和 organization.svc/ web 终结点中可用,但在 organizationdata.svc (OData) 终结点中不可用。
使用 JavaScript Web 资源,可以执行。详细信息:使用 JavaScript Web 资源执行操作
始终运行在呼叫用户的安全上下文中。
当活动中注册了插件步骤时,不能删除记录。
可以通过配置设置选择性地参与当前数据库事务。
不支持执行限制到用户、业务部门或组织的范围。 始终在组织范围内执行操作。
支持输入和输出参数。
支持审核数据更改。
不支持脱机客户端。
可以通过调用 Web 服务方法调用。
可以直接从工作流调用。
所需权限
需要名为活动实时流程 (prvActivateSynchronousWorkflow) 的安全特权,以激活操作的实时流程,从而执行此流程。 这是创建工作流所必需的所有权限之外的附加权限。 有关这些特权的详细信息,请参阅 “安全角色”的 中的特权 UI 映射。
使用代码创建操作
通常,定制员使用 Web 应用程序的交互式工作流设计器实施操作。 不过,如果需要,开发人员可以使用 SDK 调用实现操作,并部署到内部部署或 IFD 服务器。
下表描述了用于操作的工作流实体属性。 可以在主题 在代码中创建实时工作流 中找到实时工作流的示例代码。
工作流属性 |
说明 |
---|---|
Category |
设置为 WorkflowCategory.CustomOperation。 |
SyncWorkflowLogOnError |
当为 true 时,错误会记录到 ProcessSession 记录。 与异步工作流不同,实时工作流执行不会记录到 System Job 记录。 |
Mode |
未使用。 |
IsTransacted |
如果操作应参与数据库事务,则设置为 true;否则,设置为 false。 默认值为 true。 |
UniqueName |
操作的唯一名称。 该名称由发布者前缀 +“_”+ 唯一名称组成。 |
Xaml |
设置为对操作的实时工作流进行定义的 XAML 代码。 没有办法来引用另一个现有实时工作流。 |
添加输入和输出参数
操作支持可使用 DynamicActivityProperty 类型添加到工作流的输入和输出参数。 当您将这些参数添加到操作的工作流时,它们成为与该操作关联的消息请求和响应类中的属性。 例如,以下示例演示的是两个输入参数和一个输出参数的 C# 和 XAML 代码。
DynamicActivityProperty inputProperty1 = new DynamicActivityProperty { Name = "Subject", Type = typeof(InArgument<string>) };
DynamicActivityProperty inputProperty2 = new DynamicActivityProperty { Name = "EntityCollection", Type = typeof(InArgument<EntityCollection>) };
DynamicActivityProperty outputProperty1 = new DynamicActivityProperty { Name = "Output", Type = typeof(OutArgument<string>) };
inputProperty1.Attributes.Add(new ArgumentRequiredAttribute(true));
inputProperty1.Attributes.Add(new ArgumentDescriptionAttribute("The subject"));
inputProperty1.Attributes.Add(new ArgumentDirectionAttribute(Microsoft.Xrm.Sdk.Workflow.ArgumentDirection.Input));
inputProperty2.Attributes.Add(new ArgumentRequiredAttribute(false));
inputProperty2.Attributes.Add(new ArgumentDescriptionAttribute("The entity collection"));
inputProperty2.Attributes.Add(new ArgumentDirectionAttribute(Microsoft.Xrm.Sdk.Workflow.ArgumentDirection.Input));
outputProperty1.Attributes.Add(new ArgumentRequiredAttribute(false));
outputProperty1.Attributes.Add(new ArgumentDescriptionAttribute("The output"));
outputProperty1.Attributes.Add(new ArgumentDirectionAttribute(Microsoft.Xrm.Sdk.Workflow.ArgumentDirection.Output));
<x:Property Name="Subject"
Type="InArgument(x:String)">
<x:Property.Attributes>
<mxsw:ArgumentRequiredAttribute Value="True" />
<mxsw:ArgumentTargetAttribute Value="False" />
<mxsw:ArgumentDescriptionAttribute Value="The subject " />
<mxsw:ArgumentDirectionAttribute Value="Input" />
<mxsw:ArgumentEntityAttribute Value="" />
</x:Property.Attributes>
</x:Property>
<x:Property Name="EntityCollection"
Type="InArgument(mxs:EntityCollection)">
<x:Property.Attributes>
<mxsw:ArgumentRequiredAttribute Value="False" />
<mxsw:ArgumentTargetAttribute Value="False" />
<mxsw:ArgumentDescriptionAttribute Value="The entity collection" />
<mxsw:ArgumentDirectionAttribute Value="Input" />
<mxsw:ArgumentEntityAttribute Value="" />
</x:Property.Attributes>
</x:Property>
<x:Property Name="Output"
Type="OutArgument(x:String)">
<x:Property.Attributes>
<mxsw:ArgumentRequiredAttribute Value="False" />
<mxsw:ArgumentTargetAttribute Value="False" />
<mxsw:ArgumentDescriptionAttribute Value="The output" />
<mxsw:ArgumentDirectionAttribute Value="Output" />
<mxsw:ArgumentEntityAttribute Value="" />
</x:Property.Attributes>
</x:Property>
属性所用的名称应当与参数名称一致,因为代码生成会将它们定义为请求或者响应属性。
下表显示了输入和输出参数的受支持参数类型。
.NET 类型 |
参数类型 |
---|---|
System.Int32 |
Integer |
System.String |
String |
EntityReference |
|
Entity |
|
EntityCollection |
|
System.DateTime |
DateTime |
System.Double |
Float |
System.Decimal |
Decimal |
Money |
|
System.Boolean |
Boolean |
Picklist |
下表列出受支持的参数属性。
参数属性 |
说明 |
---|---|
指示是否需要参数。 |
|
指示参数的方向是输入还是输出。 |
|
指定参数的说明。 |
|
当您想要传入实体时使用。 |
|
自动生成或添加此参数。 它指向运行工作流的主要实体。 此参数是全局操作的可选参数。 |
打包操作以进行分发
若要分发操作以便它可以导入 Microsoft Dynamics 365 组织,请将您的操作添加到 Dynamics 365 解决方案。 使用 Web 应用程序通过导航到“设置”>“自定义项”>“解决方案”,可轻松完成此操作。 您还可以编写代码来创建解决方案。 有关解决方案的详细信息,请参阅使用解决方案打包和分发扩展。
为操作生成早期绑定类型
使用 SDK 包中提供的 CrmSvcUtil 工具,可以为您的操作生成要在应用程序代码中包括的请求和响应类。 不过,在生成这些类之前,请确保激活操作。
下载 Microsoft Dynamics CRM SDK 包。
以下示例显示在内部部署的 Dynamics 365 安装中从命令行运行该工具的格式。 需为安装提供参数值。
CrmSvcUtil.exe /url:http://<serverName>/<organizationName>/XRMServices/2011/Organization.svc /out:<outputFilename>.cs /username:<username> /password:<password> /domain:<domainName> /namespace:<outputNamespace> /serviceContextName:<serviceContextName> /generateActions
以下示例显示 Microsoft Dynamics 365 (online) 中从命令行运行该工具的格式。 您需要提供适合您的客户和服务器的参数值。
CrmSvcUtil.exe /url:https://<organizationUrlName>.api.crm.dynamics.com/XRMServices/2011/Organization.svc /out:<outputFilename>.cs /username:<username> /password:<password> /namespace:<outputNamespace> /serviceContextName:<serviceContextName> /generateActions
请注意 /generateActions 参数的使用。详细信息:使用代码生成工具 (CrmSvcUtil.exe) 创建早期绑定实体类。
您可以将早期绑定或晚期绑定类型用于您的操作的已生成请求和响应类。
使用 Web API 执行操作
在创建新操作时,它是在 Web API 中创建的。 如果操作是在实体的上下文中创建的,它会绑定到该实体。 否则它是未绑定的操作。详细信息:使用 Web API 操作。
使用组织服务执行操作
若要使用组织 Web 服务托管代码执行操作,请遵循下列步骤。
在应用程序项目中包括您使用 CrmSvcUtil 工具生成的早期绑定类型文件。
在应用程序代码中,实例化操作的请求,并填充所有必需的属性。
调用 Execute,将您的请求作为参数传递。
运行应用程序代码之前,请确保操作处于激活状态。 否则,您将收到运行时错误。
使用 JavaScript Web 资源执行操作
可以使用 API Web 执行操作,就像任何系统操作一样。详细信息:使用 Web API 操作。
Sdk.Soap.js 示例库演示如何将消息用于 JavaScript Web 资源和组织服务 (organization.svc/web)。 使用伴随 Sdk.Soap.js 消息生成器 示例生成可用于 Sdk.Soap.js 的JavaScript 库,同样您还可以使用该示例中提供的系统消息库。 使用 Sdk.Soap.js 操作消息发生器生成的文件为每个操作的单独 JavaScript 库。 每个库包含对应 CrmSvcUtil 生成的类的请求和响应类。
使用流程执行操作
您可以从工作流、对话或者其他流程操作执行操作。 激活的自定义操作可用于流程,方法是在 Web 应用程序流程窗体的“添加步骤”下拉菜单中选择“执行操作”项。 在将步骤添加到您的流程后,您可以从步骤中提供的“操作”列表中选择新的自定义操作(或任意操作)。 选择步骤中的“设置属性”,指定您的自定义操作需要的任何输入参数。
备注
如果自定义操作具有不受支持的参数类型,例如选择列表、实体或实体集合,自定义操作将不在“操作”列表中列出。
从流程执行操作的功能已通过 Microsoft Dynamics CRM Online 2015 更新 1 引入。
现有 Depth 平台检查确保不会出现无限循环。 有关深度限制的详细信息,请参阅 MaxDepth。
监视长时间运行的操作
如果操作的实时工作流的步骤之一是自定义工作流活动,则与管理沙盒插件的方式类似,该自定义工作流活动将在隔离的沙盒运行时环境中执行,并受两分钟超时限制。 不过,对于操作本身花费的总体时间量,没有任何限制。 此外,如果操作参与事务,其中启用了回滚,则 SQL Server 超时将应用。
提示
最佳做法建议是,应当使用 .NET 异步或后台进程在 Microsoft Dynamics 365 之外执行长时间运行的操作。
另请参阅
创建实时工作流
使用 Dynamics 365 中的对话完成引导式流程
事件执行管道
使用Dynamics 365 流程自动化业务流程
TechNet:自定义您的系统
Microsoft Dynamics 365
© 2017 Microsoft。 保留所有权利。 版权