我正在尝试编写一个 MS Dynamics CRM 2011 插件以在沙盒模式下运行,但使用来自 GAC 程序集的类。我遇到了一个问题,即从 GAC 程序集创建类型列表会产生错误,我不明白为什么。生成的异常属于类型System.MethodAccessException
并具有以下消息:
Attempt by method 'IsolatedModeExceptionsTestingPlugin.Plugin.Execute(System.IServiceProvider)' to access method 'System.Collections.Generic.List`1<System.__Canon>..ctor()' failed.
有人可以解释为什么这会失败,以便我可以修改我的代码/环境来解决失败吗?
我在下面的一组简单的类中重新创建了场景。
我在运行 Dynamics 2011 Rollup 7 的 Win2008 R2 服务器上运行了测试,然后在 Rollup 11 上再次运行了测试。我的两个程序集都是针对 .Net 4.0 构建的,并且 Dynamics IIS AppPool 是为 .Net 4 配置的。两个程序集都已签名(使用相同的密钥对)。
请注意,如果我将插件的隔离模式从“沙盒”更改为“无”,插件可以正常工作——只有在沙盒模式下才会发生这种情况,这意味着在生成 List<> 时会出现某种安全违规。另请注意,创建一个 List(或其他 .Net 类型)可以正常工作,就像在我自己的程序集中创建一个 List<> 类一样。它似乎特定于 GAC 的程序集。
我在 GAC 中放置的程序集名为“ClassLibrary1”,仅包含一个类:
namespace ClassLibrary1
{
public class MyCustomAssemblyClass
{
public string GetAString()
{
return "The current time is " + System.DateTime.Now.ToString();
}
}
}
我通过在服务器(安装了 Windows SDK v7.1)上运行以下命令将它放在 GAC 中:"c:\program files\Windows SDKs\Windows\v7.1\bin\NETFX 4.0 Tools\gacutil.exe" -i classlibrary1.dll
我的插件代码如下所示:
using System.Collections.Generic;
using System.Text;
using System;
using ClassLibrary1;
using Microsoft.Xrm.Sdk;
namespace IsolatedModeExceptionsTestingPlugin
{
public class Plugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
var pluginExecutionContext = (IPluginExecutionContext) serviceProvider.GetService(typeof (IPluginExecutionContext));
var tracingService = (ITracingService) serviceProvider.GetService(typeof (ITracingService));
try
{
tracingService.Trace("Entered Plugin.Execute()");
tracingService.Trace(string.Format("Isolation Mode: {0}, Mode: {1}\n\n",
pluginExecutionContext.IsolationMode,
pluginExecutionContext.Mode));
try
{
tracingService.Trace(string.Format("*** Creating List<{0}>", typeof (MyCustomAssemblyClass)));
var list = new List<MyCustomAssemblyClass>(); //XXX Exception thrown here!!
tracingService.Trace(" Success");
}
catch (Exception ex)
{
tracingService.Trace(GetExpectionTraceMessage(ex));
throw new Exception("An error occurred in one of the tests", ex);
}
finally
{
tracingService.Trace("*** Finished TestListOfGACClassCxtr\n\n");
}
//This will force a failure to allow viewing of the trace file
// throw new Exception("TEST SUCCESSFULL");
}
finally
{
tracingService.Trace("Exiting Plugin.Execute()");
}
}
private string GetExpectionTraceMessage(Exception ex)
{
var message = new StringBuilder();
message.AppendFormat("EXCEPTION: {0}\n", ex.GetType());
message.AppendFormat("\tMessage: {0}\n", ex.Message);
message.AppendFormat("\tStack: {0}\n", ex.StackTrace);
if (ex.InnerException != null)
{
message.AppendLine("---- INNER EXCEPTION ----");
message.AppendLine(GetExpectionTraceMessage(ex.InnerException));
}
return message.ToString();
}
}
}
当实体更新时,我将插件注册为在数据库中以沙盒模式运行。执行插件后,我通过“业务流程错误”对话框的“下载日志文件”获得以下输出:
Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: Unexpected exception from plug-in (Execute): IsolatedModeExceptionsTestingPlugin.Plugin: System.Exception: An error occurred in one of the testsDetail:
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
<ErrorCode>-2147220956</ErrorCode>
<ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<Message>Unexpected exception from plug-in (Execute): IsolatedModeExceptionsTestingPlugin.Plugin: System.Exception: An error occurred in one of the tests</Message>
<Timestamp>2012-11-29T18:09:26.5671559Z</Timestamp>
<InnerFault i:nil="true" />
<TraceText>
[IsolatedModeExceptionsTestingPlugin: IsolatedModeExceptionsTestingPlugin.Plugin]
[6d245108-b638-e211-bae5-000c29d5e4ba: IsolatedModeExceptionsTestingPlugin.Plugin: Update of new_insurancequote]
Entered Plugin.Execute()
Isolation Mode: 2, Mode: 0
*** Creating List<ClassLibrary1.MyCustomAssemblyClass>
EXCEPTION: System.MethodAccessException
Message: Attempt by method 'IsolatedModeExceptionsTestingPlugin.Plugin.Execute(System.IServiceProvider)' to access method 'System.Collections.Generic.List`1<System.__Canon>..ctor()' failed.
Stack: at IsolatedModeExceptionsTestingPlugin.Plugin.Execute(IServiceProvider serviceProvider)
*** Finished TestListOfGACClassCxtr
Exiting Plugin.Execute()
</TraceText>
</OrganizationServiceFault>
作为参考,.Net 框架似乎使用 System.__Canon 类型在 JIT 中为所有泛型创建可重用代码。见: http: //www.marklio.com/marklio/PermaLink,guid,1fa8a82b-a6d6-4fbb-8cca-5e352ff3c9e9.aspx