使用 Microsoft Dynamics CRM 2015 进行开发的最佳实践
发布日期: 2016年11月
适用于: Dynamics CRM 2015
本主题介绍自定义 Microsoft Dynamics CRM 2015 和 Microsoft Dynamics CRM Online 2015 更新 的最佳实践。
本主题内容
性能最佳实践
自定义最佳实践
安全性最佳实践
ISV 扩展性最佳实践
性能最佳实践
下列最佳实践可帮助您编写性能更佳的代码。
使用多个线程
向应用程序添加线程支持可以将工作分配给多个 CPU。 此建议的前提是您正在多处理器系统上运行代码。详细信息:《NET Framework 高级开发指南》中有关“托管线程处理”的文章.
允许系统创建 GUID
允许系统自动为您分配 GUID (Id),而不是让您自己手动创建它。 此建议允许 Microsoft Dynamics 365 利用顺序 GUID,这将提供更佳的 SQL 性能。 以下示例代码演示如何调用 Create 方法以获取系统分配的 GUID。
// Instantiate an account object.Account account = new Account { Name = "Fourth Coffee" };
// Create an account record named Fourth Coffee and retrieve the GUID.accountId = serviceProxy.Create(account);
使用早期绑定类型
在代码必须对编写代码时未知的实体和属性执行操作时,则使用 Entity 类。 此外,如果您的自定义代码用于数千条实体记录,则使用 Entity 类获得的性能会比使用早期绑定实体类型获得的性能略高一些。 但是,此灵活性有一个缺点,因为您无法在编译时验证实体和属性名。 如果您的实体在代码编写阶段已经定义且可以接受性能略微降低,则应该使用通过 CrmSvcUtil 工具生成的早期绑定类型。详细信息:在代码中使用早期绑定实体类
禁用插件
如果可以,请在运行应用程序之前禁用已注册的插件。
编写执行较快的插件
始终编写执行预定任务花费时间最少的插件。 例如,在 Microsoft Dynamics 365 中经常处理 Execute 方法。 如果您针对该消息注册插件,则插件会对系统产生显著的性能影响,因为每次处理 Execute 方法时,都会执行该插件,这会频繁发生。
如果您要同步执行注册插件,建议您将其设计为在 10 秒内完成其操作。 最好是最大程度地减少插件的处理时间以维护连接到执行该插件的同一组织服务的客户端应用程序的交互性。
限制您检索的数据
使用从服务器检索数据的方法时,检索应用程序所需的最少量的数据。 可以通过指定列集来做到这一点,列集是指要检索的实体属性的集合。 例如,应避免使用 RetrieveAllEntitiesRequest 消息,为 EntityFilters 属性指定 EntityFilters.All 实体筛选器来检索所有元数据。 相反,如果限制实体筛选器,或使用下列消息之一,则可能会实现更好的性能:RetrieveEntityRequest、RetrieveOptionSetRequest、RetrieveAttributeRequest 或 RetrieveRelationshipRequest。
限制将级联作用于相关实体的操作
使用 Update 方法或 UpdateRequest 方法时,请勿在记录上设置 OwnerId 属性,除非已实际更改了负责人。 设置此属性时,更改通常会将级联作用于相关实体,这可增加更新操作所需的时间。详细信息:级联行为
在客户端上调整代理设置(仅内部部署)
代理服务器位于客户端应用程序(如 Web 浏览器)和实际的目标服务器之间。 计算机位于 LAN 中时,可以使用代理服务器连接到 Internet。 在这种情况下,代理服务器与网关服务器和防火墙服务器协同工作,或者是网关服务器和防火墙服务器的一部分。 代理可以缓存 Web 请求,并使用缓存的数据为多个客户端请求提供服务。 如果代理服务器的缓存中不存在请求的数据,则代理服务器会使用自己的 IP 地址将请求转发到实际的服务器。 此时,代理服务器代表客户端计算机执行操作。
尽管代理服务器可以充当缓存服务器并帮助更快地加载网页,但如果使用不当,有时会降低性能。 通常,应避免使用手动代理配置而使用自动代理配置。 此快捷方式有助于在代理服务器之间实现负载平衡,但是根据配置脚本的复杂程度,使用自动代理配置时可能会遇到长时间的延迟。
如果安装的是 Microsoft Dynamics 365 服务器,您可以跳过代理服务器以提高吞吐量。 服务器会提供不需要代理即可连接的本地 Web 地址。 您可以选择“对于本地地址不使用代理服务器”,并在例外列表中提供 Microsoft Dynamics 365 服务器的完全限定域名。 使用 Microsoft Dynamics CRM SDK 创建记录时,这能提高吞吐量。
改进服务通道分配性能
可以建立与 Microsoft Dynamics 365 Web 服务的连接并使用 OrganizationServiceProxy 和 DiscoveryServiceProxy 服务代理类对用户进行身份验证。 但是,错误使用这些服务代理类有时会降低应用程序性能。 因此,如果您了解何时使用以及如何使用 SDK 中提供的不同客户端类,则通常可获得更佳的应用程序性能。
在使用服务终结点(例如,使用组织 Web 服务)建立 Windows Communication Foundation (WCF) 服务通道时,您的应用程序必须执行两项相当耗时的操作:从终结点下载元数据和用户身份认证。 如果您的应用程序对每个应用程序会话执行最小数目的此类操作,则可改进性能。 只要创建服务代理对象,如下所示的 OrganizationServiceProxy 构造函数就会同时执行这些操作。
OrganizationServiceProxy (Uri uri, Uri homeRealmUri, ClientCredentials clientCredentials, ClientCredentials deviceCredentials)
如果您的应用程序使用此构造函数创建服务代理的实例(通过在应用程序会话期间使用一次此构造函数)并缓存返回的引用以便在应用程序中的不同代码路径中使用,则您通常可获得更佳的性能。 请注意,返回的服务引用不是线程安全的服务,因此多线程应用程序将需要为每个线程分配一个实例。 此外,应用程序在终止之前还必须对服务代理对象调用 Dispose,以便释放服务通道分配资源。
服务代理类使用以下类方法执行元数据下载和用户身份验证。
IServiceManagement<IOrganizationService> orgServiceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(organizationUrl))AuthenticationCredentials authCredentials = orgServiceManagement.Authenticate(credentials)
在 Authenticate 方法对用户进行身份验证时,CreateManagement<TService> 方法将执行元数据下载。 从这些方法返回的对象是线程安全的对象,并可通过应用程序进行静态缓存。 然后,可以使用这些对象构造使用其他可用构造函数之一的服务代理对象。
OrganizationServiceProxy (orgServiceManagement, authCredentials.ClientCredentials)OrganizationServiceProxy (orgServiceManagement, authCredentials.SecurityTokenResponse)
通过缓存服务管理和经身份验证的凭据对象,您的应用程序可更高效地为每个应用程序会话多次构造服务代理对象。 如果您通过某个 EnableProxyTypes 方法启用 OrganizationServiceProxy 上的早期绑定类型,则必须对从缓存的 IServiceManagement<TService> 对象创建的所有服务代理执行同一操作。 如果您的应用程序使用元数据,则建议缓存它检索的元数据,并定期调用 RetrieveTimestampRequest 消息来确定是否必须刷新缓存。
此外,监控您的 WCF 安全令牌 (Token),在该令牌到期之前刷新它,避免因丢失令牌而必须重新开始身份验证。 若要检查令牌,可以创建一个继承自 OrganizationServiceProxy 或 DiscoveryServiceProxy 类的自定义类,该自定义类将实现业务逻辑以检查令牌。 或将这些代理类包装在一个新类中。 另一种技术是在每次调用 Web 服务之前,显式检查令牌。 演示这些技术的示例代码位于帮助程序代码:ServerConnection 类主题的 ManagedTokenDiscoveryServiceProxy、ManagedTokenOrganizationServiceProxy 和 AutoRefreshSecurityToken 类中。
自定义最佳实践
以下最佳实践可帮助您自定义和扩展 Microsoft Dynamics 365。
Microsoft Dynamics CRM Online 最佳实践
Microsoft Dynamics CRM Online 解决方案生成器的模式和原理 白皮书下载为使用 Microsoft Dynamics CRM Online 构建解决方案提供了特别的指导。
使用自定义实体和属性
通过使用这些技术来节省服务器上的空间:
对现有实体创建自定义属性,而不创建新的实体。
重新命名现有的实体以使实体更具有意义。
何时应该自定义实体?
自定义诸如商机实体之类的系统实体而不是用新的自定义实体替换它,以便您可在现有实体中使用多项内置功能。 例如,商机和案例实体具有查找字段以关联客户。 客户可以是帐户或联系人。 无法创建具有相同的查找类型的自定义实体。 可以更改系统实体的显示名称以使实体对您的业务更有意义。
何时使用插件与工作流?
作为一名有兴趣扩展或自定义 Microsoft Dynamics 365 的开发人员,您可从多种方法中选择适当的方法来执行任务。 除了向窗体中添加客户端 JavaScript 代码或添加自定义 ASP.NET 页面外,您还可以选择通过使用调用自定义工作流活动的 Web 界面来编写插件或创建自定义工作流。 如何决定什么时候使用插件,什么时候使用工作流? 使用的技术取决于必须执行的任务和将要创作自定义项的人。
例如,如果需要在核心平台操作执行之前或之后,并在操作结果从平台中返回之前立即执行自定义代码,则必须使用同步插件实时工作流。 这种情况下,不能使用异步工作流或异步插件,因为它们会排入队列,在核心操作执行完成后才能执行。 因此,您无法预测它们将何时执行。 如果要将自定义功能添加到 Microsoft Dynamics CRM Online,则支持工作流和插件,但不支持自定义工作流活动。
评估这些技术,综合考虑插件或工作流解决方案的部署、性能和维护等方面,然后选择一种最符合业务目标的技术。
下表总结了插件和工作流的特性。
条件 |
插件 |
工作流 |
---|---|---|
在核心平台操作(创建、更新、删除等)之前或之后执行 |
在核心操作之前或之后立即执行(同步)。 可以排入队列以在核心操作之后执行(异步)。 |
异步工作流可以排入队列,以在核心操作之后执行。 实时工作流与插件有类似的特点。 |
对服务器性能的影响 |
同步插件可能会增加平台响应时间,因为它们是主要平台处理过程的一部分。 异步插件对服务器响应时间的影响较小,因为代码在不同的进程中运行。 |
异步工作流对服务器响应时间的影响较小,因为代码在不同的进程中运行。 实时工作流与沙盒插件有类似的性能特点。 |
安全限制 |
向平台注册插件需要系统管理员或系统定制员安全角色以及“部署管理员”组的成员资格。 |
用户可以在 Web 应用程序中以交互方式创建工作流。 但是,要注册自定义工作流活动,进行部署的用户必须具有与注册插件所需的相同安全角色。 |
Microsoft Dynamics 365 版本 (SKU) 支持 |
在沙盒中注册后则在 Microsoft Dynamics CRM Online 中受支持。 可以在合作伙伴托管的安装中受支持,这由合作伙伴自行决定。 |
所有 Dynamics 365 部署均支持工作流。 在沙盒 Microsoft Dynamics CRM Online 中或在内部部署 /IFD 部署的沙盒中或沙盒外支持自定义工作流活动。 |
处理时间的长短 |
针对同步或非同步执行注册的插件要求在 2 分钟的时间限制内完成其执行。 |
既适用于短期进程也适用于长期进程。 但是,工作流中的每个活动所需完成时间不能超过两分钟。 |
在 Dynamics CRM for Outlook 客户端脱机的情况下也工作 |
联机和脱机均支持。 |
脱机时工作流不执行。 |
进程和数据持久性 |
插件执行直至完成。 必须将插件编写成无状态的情况,即不保留任何内存中数据。 |
异步工作流可以通过 SDK 调用或由用户通过 Web 应用程序进行暂停、推迟、取消和恢复。 在暂停或推迟工作流之前,系统会自动保存工作流的状态。 实时工作流不能包含任何等待状态。 它们的执行必须完成地与插件一样。 |
模拟 |
插件可以代表其他系统用户执行数据操作。 |
异步工作流无法使用模拟,实时工作流则可以。 实时工作流可以以工作流负责人或调用用户的身份执行。 |
创作 |
软件工程师或程序员能创作插件。 |
包括最终用户、业务分析师和管理员在内的所有人,只要具有相应的权限,就能创作工作流。 |
异步插件和工作流对服务器性能没有太大影响。
哪种类型的工作流更好?
从性能角度考虑,是创建单个长工作流更好一些,还是使用多个子工作流并在一个父工作流中调用它们更好一些? 子工作流方法可实现吞吐量降低,但更易于管理(如果频繁更改工作流定义)。 编译开销不是主要问题,因为仅在发布期间才会编译工作流。 但是,Microsoft Dynamics 365 在启动每个工作流实例时会产生开销。 在检索工作流中使用的所有实体并在一个 2 步骤过程(包括“工作流扩展任务”和实际工作流实例)中启动子工作流时,会产生开销。 因此,为实现最大吞吐量,请使用单个长工作流。
应如何将您的自定义工作流活动标记为已完成?
从 Execute 方法返回的值供工作流运行时用来将活动标记为“已完成”。 除非活动绕过基类功能,否则应该使用 return base.Execute(executionContext)。 避免返回 ActivityExecutionStatus.Closed。详细信息:ActivityExecutionStatus 枚举
应如何报告自定义工作流活动中的例外?
您应在代码中引发 InvalidPlugInExecutionException。 将在工作流实例窗体中显示此错误。
是否可定义特定于业务部门的自定义实体?
自定义实体的权限是针对每个安全角色的,而不是针对每个业务部门。 要定义只有特定业务部门可见的自定义实体,您必须为每个业务部门创建不同的安全角色,然后向相应角色中的自定义实体授予权限。
安全性最佳实践
按照这些指南操作可以帮助您保护业务数据。
常规
保护 Microsoft Dynamics 365 实现的安全的最佳实践包括以下这些:
针对组织的 Microsoft Dynamics 365 实现制定经过批准的安全数据计划。
在设置应用程序池时分配所需的最小权限。
要求所有用户对其帐户使用强密码。 有关详细信息,请在 Windows 帮助中搜索“强密码”。
详细信息:TechNet:Microsoft Dynamics CRM 的安全注意事项
角色、权限和访问权限
使用 Microsoft Dynamics 365 安全模型的最佳实践包括下列几项:
严格限制分配系统管理员角色的用户数量。 切勿删除此角色。
根据安全性最佳实践中的最低权限原则创建角色,提供对执行任务所需的最少量业务数据的访问权限。 为用户分配完成作业所需的适当权限。
如果用户需要附加访问级别或权限,请创建具有这些特定权限的新角色,并将该用户添加到新角色。 用户的权限是为其分配的所有角色的并集。 不要授予只有一个或少数成员需要的原始角色权限。
在适当时使用共享为特定用户授予对单个对象的特定权限,而不是对给定类型的所有对象的更广泛的权限。
使用团队创建交叉职能组,以便可以与团队共享特定对象。
对具有共享访问权限的用户进行培训,以共享所需的最少量的信息。
避免权限提升
当某个用户可以篡夺受信帐户(例如负责人或管理员)的权限时,则会发生权限提升攻击。 始终在最低权限的用户帐户下运行,并仅指派所需的权限。 避免使用管理或负责人帐户执行代码。 这可以限制攻击成功的情况下受损可以达到的程度。 执行需要更多权限的任务时,请仅在任务的执行期间使用过程签名或模拟。
服务器端开发
为 Microsoft Dynamics 365 开发服务器端代码的最佳实践包括下列几项:
请勿使用除 SDK 以外的任何其他方式修改 Microsoft Dynamics 365 数据库,因为其会绕过 Microsoft Dynamics 365 安全模型。
插件在管理员上下文中运行,您应该了解此代码可能会访问登录的用户无权访问的信息。
对于工作流程序集和插件,避免编写执行时需要花费很长时间的代码。 有一点很重要,就是注册同步执行的插件代码返回的时间要尽可能短。
如果要复制自己的数据存储中的 Microsoft Dynamics 365 数据,您应该对数据的安全负责。 如果使用插件传输数据,请确保在核心平台操作完成之后再注册插件进行执行。 登录用户的安全权限检查在核心平台操作的期间执行。
呈现从 Microsoft Dynamics 365 获取的数据可能不安全。 数据中可能插入了不安全的 HTML 标记。
遵循不直接通过 Microsoft Dynamics 365 企业管理器访问 SQL Server 数据库的要求。 不使用 SDK 可能会使您面临 SQL 注入威胁。
对于面向 Internet 的部署,请记住解决方案的安全性取决于最薄弱的一环。 应用程序面向 Internet 公开后,会面临安全威胁。
仅使用生成托管代码的语言,以实现最佳安全性,防止出现缓冲区溢出和异常等等。
有关安全性的更多详细信息,请参阅以下主题:
客户端开发
为 Dynamics 365 Web 应用程序和 Microsoft Dynamics CRM for Outlook 开发自定义项的最佳实践包括:
尽可能使用 Web 资源,而不使用需要服务器端处理的页面。 如果您的要求只能通过服务器端处理才能满足,则请遵循下面的要求:从 Microsoft Dynamics 365 将自定义网页安装在单独的网站上。 根据代码安全性中的可信度,相应地设置您的网站的信任级别。 这样可减小来自跨网站脚本的威胁和其他威胁。
为提高安全性,确保使用不同于 Microsoft Dynamics 365 的帐户运行您的单独网站。 此帐户具有的访问权限应该尽可能少,并且不能直接访问 Microsoft 数据库。 可以使用复杂的、不会过期的密码,因为除了登录您的应用程序外,没有人会登录此帐户。
避免使用 ActiveX 控件,因为它们存在已知的安全问题。
请注意客户端脚本的限制。详细信息:为 Microsoft Dynamics CRM 2015 窗体编写代码
无论如何进行数据更改,请使用插件来应用业务逻辑。
在删除记录或应用敏感更改(例如,将新用户添加到安全角色)时始终使用确认对话框。 您可以将 Xrm.Utility.confirmDialog 用于此目的。 这有助于防止诸如点击劫持或界面伪装漏洞之类的技术,在这些技术中恶意的开发人员可能会将您的页面嵌入到一个看似安全的页面,以诱使用户执行降低安全的操作或对数据执行不需要的操作。
网站的安全性最佳实践包括以下这些:
不要使用匿名访问。
对 安全套接字层 (SSL) 使用集成 Windows 身份验证、NTLM 或 Basic 身份验证。
如果您的网站与 Microsoft Dynamics 365 位于不同的计算机上,使用 SSL 可避免通过网络发送未加密数据。
有关详细信息,请参阅以下内容:
ISV 扩展性最佳实践
ISV 扩展性的一项关键原则是不应该假定您的 ISV 解决方案是安装的唯一解决方案。 以下是要遵循的最佳实践列表。
使用 Microsoft Dynamics CRM web 服务的最佳实践示例
应该将 Microsoft Dynamics 365 Web 服务 URL 放入配置文件(例如,放入 app.config 文件)中,以便将代码与对 URL 的更改隔离开。 例如,全球各地的三大 Microsoft Dynamics CRM Online 数据中心的 URL 都不同。
应该将插件和自定义工作流活动放置在何处?
对于磁盘上的插件或自定义工作流活动,请将程序集放在 <installdir>\Server\bin\assembly 文件夹中。
应该将自定义 Web 应用程序或网页放置在何处?
请参阅主题从 ASPX 网页或 IFRAME 实施单一登录。
当 Web 应用程序的网格视图更新时,您如何执行一个插件?
在 RetrieveMultipleRequest 消息请求上注册该插件,但在注册期间不指定任何实体类型。
何时应该创建新的网站?
在以下任一情况下,为您的代码创建新网站:
您的应用程序必须绑定到与 Microsoft Dynamics 365 应用程序不同的域、协议或端口,或者必须在不同应用程序池中运行。
您的应用程序可独立存在和单独进行访问。 例如,作为服务器(使用 Web 服务)与 Microsoft Dynamics 365 交互的门户应作为新网站进行托管。
您的应用程序始终使用 Active Directory 或集成 Windows 身份验证(非 IFD),并且无需考虑跨域脚本问题。 例如,您的应用程序与使用 Web 服务的后端交互,同时还与 Microsoft Dynamics 365 窗体交互。 托管在不与 Microsoft Dynamics 365 窗体交互的 Microsoft Dynamics 365 应用程序包含的 IFRAME 中的页面属于这个类别。
另请参阅
编写应用程序和服务器扩展
设置位标志
为 Microsoft Dynamics CRM 2015 窗体编写代码
编写插件以扩展业务流程
自定义工作流活动(工作流程序集)
© 2017 Microsoft。 保留所有权利。 版权