MethodAccessException:方法 X 尝试访问方法 Y 在 Dynamics 365 Plugin On Prem 中失败

MethodAccessException: Attempt by method X to access method Y failed in Dynamics 365 Plugin On Prem

在 Dynamics 365 v9.1 中尝试将插件从 .NET 版本 4.5.2 移动到 4.6.2 时出现以下错误

 System.AggregateException: One or more errors occurred. ---> System.MethodAccessException: Attempt by method 'System.Net.Http.WinHttpResponseParser.GetReasonPhrase(System.Net.HttpStatusCode, Char[], Int32)' to access method 'System.Net.HttpStatusDescription.Get(System.Net.HttpStatusCode)' failed.
   at System.Net.Http.WinHttpResponseParser.GetReasonPhrase(HttpStatusCode statusCode, Char[] buffer, Int32 bufferLength)
   at System.Net.Http.WinHttpResponseParser.CreateResponseMessage(WinHttpRequestState state, Boolean doManualDecompressionCheck)
   at System.Net.Http.WinHttpHandler.<StartRequest>d__103.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Net.Http.HttpClient.<FinishSendAsync>d__58.MoveNext()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)

我可以部署插件并且它工作正常。当插件尝试对我们从插件

调用的外部 API 进行 Web 服务调用时,出现上述错误

该插件未处于沙盒模式并且已在数据库中注册

我用 JustDecompile 打开了插件程序集,并追踪到 System.dll 中加载一个方法的问题,看起来它试图从 GAC 加载它但失败了。

有人遇到同样的问题吗?这个相同的插件在 .NET 4.5.2 中工作,但在 4.6.2

中失败

我们设法为此找到了解决方案,问题是 ILMerge 包含所有 System.*.dll,阅读此 Whosebug 答案

You might want to avoid merging anything that's part of the .NET Framework (which I assume that libraries like System.Memory and System.Threading.Tasks are).

因此在 .NET 项目文件中为 ILMerge 添加行 <Files Remove="$(TargetDir)System*.dll" /> 解决了这个问题,这确保了 运行 ILMerge

时不包含文件
<Target Name="ILMerge" AfterTargets="Build">
<ItemGroup>
    <Files Include="$(TargetDir)*.dll" />
    <Files Remove="$(TargetDir)$(AssemblyName).dll" /> 
    <Files Remove="$(TargetDir)AntiXSSLibrary.dll" />
    <Files Remove="$(TargetDir)Microsoft*.dll" />
    <Files Remove="$(TargetDir)System*.dll" />
</ItemGroup>