前言

前几天偶然看到了罗勇博客中介绍 Image 在各种消息阶段的使用,让我想起之前自己也有类似的实践。不过最近很长一段时间没有写过相关的内容了,正好趁今天有空余时间,再尝试一下,顺便记录下来,以便日后查阅参考。

在实施 Dynamics CRM 项目过程中,有时候需要在实体更新操作前后执行一些自定义逻辑时,所以 PreEntityImages 和 PostEntityImages 这两个属性就发挥了重要作用。我将通过一个代码示例,演示如何使用这两个属性来获取实体数据,并进行相应的处理。

示例代码

代码如下:

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Text;

namespace Blog.D365.Plugins.Account
{
    public class AccountPostUpdate : IPlugin
    {
        private const string addressLine1 = "address1_line1";
        private const string addressLine2 = "address1_line2";
        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracer = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            try
            {
                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                {
                    Entity currentEntity = (Entity)context.InputParameters["Target"];
                    IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    IOrganizationService service = factory.CreateOrganizationService(context.UserId);
                    IOrganizationService serviceAdmin = factory.CreateOrganizationService(null);
                    Entity preEntityImages, postEntityImages = new Entity();

                    // Get PreEntityImages
                    if (context.PreEntityImages.Contains("PreImg"))
                        preEntityImages = context.PreEntityImages["PreImg"];
                    else
                        throw new InvalidPluginExecutionException("Pre Update image - PreImg does not exist!");

                    // Get PostEntityImages 
                    if (context.PostEntityImages.Contains("PostImg"))
                        postEntityImages = context.PostEntityImages["PostImg"];
                    else
                        throw new InvalidPluginExecutionException("Post Update image - PostImg does not exist!");

                    // Get RetrieveEntity
                    Entity retrieveEntity = serviceAdmin.Retrieve("account", currentEntity.Id, new ColumnSet("address1_line1", "address1_line2"));

                    StringBuilder strBuilder = new StringBuilder(); // Build output message

                    AppendAddressInfo(strBuilder, postEntityImages, "postEntityImages", addressLine1);
                    AppendAddressInfo(strBuilder, preEntityImages, "preEntityImages", addressLine1);
                    AppendAddressInfo(strBuilder, retrieveEntity, "retrieveEntity", addressLine1);
                    AppendAddressInfo(strBuilder, currentEntity, "currentEntity", addressLine1);

                    AppendAddressInfo(strBuilder, postEntityImages, "postEntityImages", addressLine2);
                    AppendAddressInfo(strBuilder, preEntityImages, "preEntityImages", addressLine2);
                    AppendAddressInfo(strBuilder, retrieveEntity, "retrieveEntity", addressLine2);
                    AppendAddressInfo(strBuilder, currentEntity, "currentEntity", addressLine2);

                    throw new InvalidPluginExecutionException(strBuilder.ToString()); // print
                }

            }
            catch (Exception ex)
            {
                tracer.Trace($"AccountPostUpdate unexpected exception:\n{ex.Message}");
                throw;
            }
        }
        private void AppendAddressInfo(StringBuilder strBuilder, Entity entity, string entityName,string addressField)
        {
            if (entity.Contains(addressField))
                strBuilder.Append($"{entityName} contains attribute “{addressField}” = {entity.GetAttributeValue<string>(addressField)};\n");
            else
                strBuilder.Append($"{entityName} does not contain attribute “{addressField}”;\n");
        }
    }
}

插件注册和Image

  • 插件注册 01

  • 添加的Image信息 02

验证

情况1

原本两个字段都未填写数据,现在分别填写 “东海” 、“西海” ,结果如下。

修改前修改后
address1_line1 = nulladdress1_line1 = “东海”
address1_line2 = nulladdress1_line2 = “西海”

结果:

postEntityImages contains attribute “address1_line1” = 东海; 
preEntityImages does not contain attribute “address1_line1”; 
retrieveEntity contains attribute “address1_line1” = 东海; 
currentEntity contains attribute “address1_line1” = 东海; 

postEntityImages contains attribute “address1_line2” = 西海; 
preEntityImages does not contain attribute “address1_line2”; 
retrieveEntity contains attribute “address1_line2” = 西海; 
currentEntity contains attribute “address1_line2” = 西海;

情况2

原本两个字段都有数据现在分别修改为 “柴安” 和 “郦三娘” 。结果如下。

修改前修改后
address1_line1 = “小明”address1_line1 = “柴安”
address1_line2 = “小李”address1_line2 = “郦三娘”

结果:

postEntityImages contains attribute “address1_line1” = 柴安; 
preEntityImages contains attribute “address1_line1” = 小明; 
retrieveEntity contains attribute “address1_line1” = 柴安; 
currentEntity contains attribute “address1_line1” = 柴安; 

postEntityImages contains attribute “address1_line2” = 郦三娘; 
preEntityImages contains attribute “address1_line2” = 小李; 
retrieveEntity contains attribute “address1_line2” = 郦三娘; 
currentEntity contains attribute “address1_line2” = 郦三娘; 

情况3

原本两个字段都有数据,现在只修改 address1_line1 为 “柴安” ,结果如下。

修改前修改后
address1_line1 = “小明”address1_line1 = “柴安”
address1_line2 = “小李”(不修改)
postEntityImages contains attribute “address1_line1” = 柴安; 
preEntityImages contains attribute “address1_line1” = 小明; 
retrieveEntity contains attribute “address1_line1” = 柴安; 
currentEntity contains attribute “address1_line1” = 柴安; 

postEntityImages contains attribute “address1_line2” = 小李; 
preEntityImages contains attribute “address1_line2” = 小李; 
retrieveEntity contains attribute “address1_line2” = 小李; 
currentEntity does not contain attribute “address1_line2”; 

情况4

原本两个字段都有数据,现在只修改 address1_line2 为 “郦三娘” ,结果如下。

修改前修改后
address1_line1 = “小明”(不修改)
address1_line2 = “小李”address1_line2 = “郦三娘”
postEntityImages contains attribute “address1_line1” = 小明; 
preEntityImages contains attribute “address1_line1” = 小明; 
retrieveEntity contains attribute “address1_line1” = 小明; 
currentEntity does not contain attribute “address1_line1”; 

postEntityImages contains attribute “address1_line2” = 郦三娘; 
preEntityImages contains attribute “address1_line2” = 小李; 
retrieveEntity contains attribute “address1_line2” = 郦三娘; 
currentEntity contains attribute “address1_line2” = 郦三娘; 

情况5

原本两个字段都有数据,现在将 address1_line1 清空, address1_line2 不变,结果如下。

修改前修改后
address1_line1 = “小明”address1_line1 = null
address1_line2 = “小李”(不修改)
postEntityImages does not contain attribute “address1_line1”; 
preEntityImages contains attribute “address1_line1” = 小明; 
retrieveEntity does not contain attribute “address1_line1”; 
currentEntity contains attribute “address1_line1” = ; 

postEntityImages contains attribute “address1_line2” = 小李; 
preEntityImages contains attribute “address1_line2” = 小李; 
retrieveEntity contains attribute “address1_line2” = 小李; 
currentEntity does not contain attribute “address1_line2”;

情况6

原本 address1_line1 没有值,address1_line2 有值,现在将 address1_line1 填写为 “柴安” ,结果如下。

修改前修改后
address1_line1 = nulladdress1_line1 = “柴安”
address1_line2 = “小李”(不修改)
postEntityImages contains attribute “address1_line1” = 柴安; 
preEntityImages does not contain attribute “address1_line1”; 
retrieveEntity contains attribute “address1_line1” = 柴安; 
currentEntity contains attribute “address1_line1” = 柴安;
 
postEntityImages contains attribute “address1_line2” = 小李; 
preEntityImages contains attribute “address1_line2” = 小李; 
retrieveEntity contains attribute “address1_line2” = 小李; 
currentEntity does not contain attribute “address1_line2”;