另一个程序集中定义了名为“account”的代理类型。

9
  • 我们在本地crm 2011系统中运行了2个组织。
  • 我们已经为这两个组织生成了早期绑定类。
  • 当停用帐户时,其中一个插件会抛出“另一个程序集定义了名称为account的代理类型”的错误。
  • 该插件仅引用早期绑定的dll之一。

我该如何让CRM系统尊重这些引用的命名空间。
我已经尝试了从Google中获得的一些方法,但都没有起作用。

由于您可以通过两个普通组织来复现此问题,我认为我们可以在不必返回并重构大量代码的情况下,在代码层外做一些事情。

谢谢,
Jon


插件是否在沙盒中注册?您确定生成的文件的命名空间是不同的吗? - ccellar
7个回答

8
问题实际上出在WCF试图反序列化服务器响应时无法识别正确的类型。解决此问题的最佳方法是在创建代理时使用Assembly.GetExecutingAssembly()将当前程序集传递给ProxyTypesBehavior()。
using (serviceProxy = new OrganizationServiceProxy(config.OrganizationUri,
                config.HomeRealmUri,
                config.Credentials,
                config.DeviceCredentials))
        {
            // This statement is required to enable early-bound type support.
            serviceProxy.ServiceConfiguration.CurrentServiceEndpoint.Behaviors.Add(new ProxyTypesBehavior(Assembly.GetExecutingAssembly()));
        }

如果您需要使用OrgnizationService(Microsoft.Xrm.Client.Services.OrganizationService)实例执行此操作(就像使用CrmConnection一样),那么您需要创建一个包装器类来访问ToOrganizationServiceProxy方法并删除默认行为,然后添加上述新行为。 - GotDibbs

4
当引用包含代理类的不同程序集时,例如包装服务器 SDK(Microsoft.Xrm.Sdk)的一个程序集和包装客户端 SDK(Microsoft.Xrm.Sdk.Client)的另一个程序集,你可能会遇到此问题。 在这种情况下,需要告诉 OrganizationServiceProxy 应使用哪个程序集来解析代理类。以下内容应该能够帮助解决问题:
var credentials = new ClientCredentials();
credentials.Windows.ClientCredential = new System.Net.NetworkCredential(userName, password, domain);

var proxy = new OrganizationServiceProxy(new Uri(discoveryUrl), null, credentials, null);
proxy.EnableProxyTypes(typeof(CrmServiceContext).Assembly);

var context = CrmServiceContext(proxy);

重要的是通过传递正确的程序集来调用EnableProxyTypes函数。我看到另一个使用CrmConnection的解决方案,但是CrmConnection仅在客户端SDK中可用,这意味着您无法以这种方式实例化"server-OrganizationServiceProxy"。 EnableProxyTypes(程序集程序集)对两侧都有效。

希望这可以帮助您。

问候, MH


1

这个问题可能已经被提出多年了。然而,我最近遇到了这个问题,并且一直非常担心需要改变成千上万行的代码。但是,我很幸运地找到了以下简单的更改方法来使自己摆脱困境:

假设您要处理两个上下文对象:

  1. 一个OrganizationServiceContext对象:context1
  2. 一个CrmSvcUtil Context对象:context2

以及一个单一的OrganizationServiceProxy对象:service

如果在单个方法中,您使用相同的service对象但是用上述任何一个上下文对象执行多个CRUD操作,则高度可能会引发此错误。但是,通过以下操作,您可以预防此类情况的发生。

每次要使用context1时,您都要在service对象之前加上context对象,如下所示:

service.EnableProxyTypes(typeof(OrganizationServiceContext).Assembly);
using (var context1 = new OrganizationServiceContext(_service)){
    // your classic code here
}

此外,每次想要使用context2时,都需要按照相同的结构进行操作:
service.EnableProxyTypes(typeof(HiwebContext).Assembly);
using (var context = new XYZContext(this._service)){
    // your CrmSvcUtil  none-classic code here
}


                      

0
我发现添加Assembly.GetExecutingAssembly()解决了这个问题。

0

加入 Assembly.GetExecutingAssembly() 解决了我的问题,你还需要添加 using System.Reflection;

谢谢


0

这通常意味着有一个或多个程序集具有相同的方法名或属性,为了解决这个问题,请使用程序集的完全限定名称。例如,在使用 System.IO 时,如果您在类代码中有一个同名的方法与 System.IO 冲突... 您应该像这样编写解决方案: thisObject.System.IO.Path( ---- ) = something for example.. 这讲得通吗?


谢谢您的评论。我认为这是CRM 2011特定问题,涉及到反射加载和缓存,而不是模糊引用。 - user1231231412
CRM是否使用类似于加载特定程序集的东西?抱歉我误解了。 - MethodMan
1
没关系,我认为没有人真正理解CRM在做什么:D。是的,根据我所读的,CRM在所有组织中都进行某种类型的类型缓存。这会导致明显的问题,因为它们全部具有相同的内置类型。 - user1231231412

0
问题也出现在使用OpenAPI和新的Dataverse Client(ServiceClient)的.Net6上。 我找到的唯一解决方法是克隆已设置好程序集引用的ServiceClient。
ServiceClient serviceClient = new ServiceClient(new Uri(Environment.GetEnvironmentVariable("DataverseUrl")), Environment.GetEnvironmentVariable("DataverseClientId"), Environment.GetEnvironmentVariable("DataverseSecret"), false, log);

ServiceClient service = serviceClient.Clone(Assembly.GetExecutingAssembly(), log);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接