本节我们来看看Dynamics CRM 2011中的插件。插件和之前文件介绍的JS编程系列中的JS在系统中扮演的角色类似,主要用来控制系统的业务流程。比如用插件来对某个值进行Sum操作,用JS来控制实体Form上某个字段是否需要隐藏等。它们的主要区别在于:插件实在服务器端进行控制的,JS则是在浏览器上进行控制的。
那什么时候使用插件呢?一般情况下能用JS实现的操作都不建议使用插件,原因有二:1.难调试;2难管理。但如果进行的操作非得在服务器端实现时就必需使用插件:对子实体上某属性进行Sum求和后,回写进到父实体的某个属性中。
在Dynamics CRM 2011 系统中有两种类型的插件:1 托管型插件,2非托管型插件。他们之间的区别是:非托管类型的插件可以访问互联网,而托管的不行。我们来看几个例子吧。
例子一 简单的插件
实现需求:在创建客户记录时自动填写该记录中的属性值“主要电话”
图1 为插件签名
图2
图3
图4
插件代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
namespace account_plugins
{
public class create_post_account:IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = serviceProvider.GetService(typeof(IPluginExecutionContext)) as IPluginExecutionContext;
IOrganizationServiceFactory factory = serviceProvider.GetService(typeof(IOrganizationServiceFactory)) as IOrganizationServiceFactory;
IOrganizationService service = factory.CreateOrganizationService(null);
Entity curEntity = null;
if (context.InputParameters.Contains("Target"))
{
curEntity = (Entity)context.InputParameters["Target"];
}
if (!curEntity.Attributes.Contains("telephone1"))
{
curEntity.Attributes.Add("telephone1", "135********");
}
service.Update(curEntity);
}
}
}
例子二 完成Sum功能的插件
实现需求:每当客户记录下的关联实体“客户”创建一条子客户记录时,重新计算属性值“子客户数”。计算公式为:子客户数=sum(关联的子客户记录)。
图1
图2
图3
图4
插件代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
namespace account_plugins
{
public class create_post_account_count_childaccount:IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = serviceProvider.GetService(typeof(IPluginExecutionContext)) as IPluginExecutionContext;
IOrganizationServiceFactory factory = serviceProvider.GetService(typeof(IOrganizationServiceFactory)) as IOrganizationServiceFactory;
IOrganizationService service = factory.CreateOrganizationService(null);
Entity curEntity = context.InputParameters["Target"] as Entity;
if(!curEntity.Attributes.Contains("parentaccountid"))
{
return;
}
Guid parentId = ((EntityReference)curEntity["parentaccountid"]).Id;
FetchExpression fetchExpression = new FetchExpression("sumChildAccount");
fetchExpression.Query = string.Format(@"<fetch mapping='logical' aggregate='true'>
<entity name='account'>
<attribute name='accountid' aggregate='countcolumn' alias='account_sum' />
<filter>
<condition attribute='parentaccountid' operator='eq' value='9e1a6fec-536b-e111-8668-000c292c54be' />
</filter>
</entity>
</fetch>", parentId );
EntityCollection result = service.RetrieveMultiple(fetchExpression);
string accountCount = ((AliasedValue)result.Entities[0]["account_sum"]).Value.ToString();
Entity uptAccount = new Entity();
uptAccount.LogicalName = "account";
uptAccount.Id = parentId;
uptAccount.Attributes.Add("new_subaccount_num", accountCount);
service.Update(uptAccount);
}
}
}
例子三 访问互联网资源的插件
实现需求:创建客户记录时,访问“http://www.baidu.com”页面。并将该页面中的html代码通过错误对话框的形式抛出。
图1
图2
图3
插件代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Query;
namespace SandboxPlugins
{
public class RetrieveAccount:IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
WebClient client = new WebClient();
string result = string.Empty;
using (Stream tmp = client.OpenRead(new Uri("http://www.baidu.com")))
{
using (StreamReader reader = new StreamReader(tmp))
{
result = reader.ReadToEnd();
}
}
throw new InvalidPluginExecutionException(result);
}
}
}