如何在CRM 2011中从IWorkflowContext访问的服务上启用ProxyTypes



我有一个C#工作流,我正试图在其中创建一个启用了代理类型的IOrganzationService,这样我就可以使用早期绑定的数据类型。。。

这就是我创建IOrganizationSerivce 的方式

IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

但是,由于我没有OrganizationServiceProxy对象,我无法在服务上调用EnableProxyTypes(),并且使用早期绑定实体在服务上的任何创建调用都会失败。

我知道我可以恢复到在app.config中设置服务器url url、sdk服务器url和组织,并使用它来创建OrganizationServiceProxy,但似乎我应该能够在我已经拥有的IOOrganizationService上设置EnableProxyTypes。。。

更新

我相信这是2011年和2013年的一个错误,早就解决了。请参阅Jim的答案,并附上一个链接,说明为什么您不应该在2015年或更新的实例中使用已接受的答案。

这是一篇旧文章,解决了一个很久以前就解决的问题。但是这里提供的一些变通方法不受支持,并且会导致使用它们的工作流活动中断。

请参阅:删除在自定义工作流活动中使用反射的不受支持的代码

要在工作流上下文中使用早期绑定实体,请尝试以下片段:

IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
var type = Type.GetType("Microsoft.Crm.Workflow.SynchronousRuntime.WorkflowContext, Microsoft.Crm.Workflow, Version=5.0.0.0");
type.GetProperty("ProxyTypesAssembly").SetValue(serviceFactory, typeof(YourServiceContext).Assembly, null); //YourServiceContext - the name of crm context
IOrganizationService service = serviceFactory.CreateOrganizationService(context.InitiatingUserId); 

正如您所看到的,有一个名为ProxyTypesAssembly的属性,它指定了保存早期绑定实体的程序集。我设置此属性的唯一方法是使用反射,因为WorkflowContextBaseWorkflowContext的基类)不可访问。

CRM 2013(以及更高版本,我希望)的修复程序要简单得多:

IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
// this is the important change
var property = serviceFactory.GetType().GetProperty("ProxyTypesAssembly");
property.SetValue(serviceFactory, typeof(YourServiceContext).Assembly, null);
IOrganizationService service = serviceFactory.CreateOrganizationService(context.InitiatingUserId); 

使用反射的答案并不理想,您将无法在沙箱隔离模式下注册程序集。

您可以将以下内容添加到插件或工作流项目中AssemblyInfo.cs文件的末尾。

[assembly: Microsoft.Xrm.Sdk.Client.ProxyTypesAssembly()]

几个月前我发现了同样的问题。您遇到的问题是由于api中的不一致。

OrganizationServiceProxy实现了只有少数成员创建、更新等的IOOrganizationService。它还继承了ServiceProxy的成员ClientCredentials、IsAuthenticated、DeviceCredentials等。

现在,在接口或抽象基类中找不到EnableProxyTypes成员。

所以基本上你运气不好。我最终使用了具体的OrganizationServiceProxy。

看看这里,自己做一下比较。

http://technet.microsoft.com/en-us/library/microsoft.xrm.sdk.iorganizationservice_members.aspx,http://technet.microsoft.com/en-us/library/microsoft.xrm.sdk.client.organizationserviceproxy.aspx,http://technet.microsoft.com/en-us/library/gg306039.aspx和http://technet.microsoft.com/en-us/library/microsoft.xrm.sdk.client.organizationserviceproxy_methods.aspx

我猜创建api的ms-crm-dev团队应该在开发早期使用tdd和一个mocking框架来学习它。

干杯Rustin

最新更新