调用nlog时的MethodAccessException LogManager.GetCurrentClassLogger()

时间:2014-11-26 03:58:18

标签: nlog castle-dynamicproxy nsubstitute

我在Web项目(ASP.NET web api)中的控制器上运行单元测试时遇到异常。执行控制器的LogManager.GetCurrentClassLogger()时抛出异常:

System.MethodAccessException:尝试方法' Castle.Proxies.ClaimsPrincipalProxy.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)'访问方法' Castle.DynamicProxy.Internal.TypeUtil.Sort(System.Reflection.MemberInfo [])'失败

它导致LogManager.GetCurrentClassLogger()中的TypeInitializationException。 这是调用堆栈:

在Castle.Proxies.ClaimsPrincipalProxy.GetObjectData(SerializationInfo,StreamingContext)    at System.Runtime.Serialization.ObjectCloneHelper.GetObjectData(Object serObj,String& typeName,String& assemName,String []& fieldNames,Object []& fieldValues)    在System.AppDomain.get_Evidence()    在System.AppDomain.get_Evidence()    在System.Configuration.ClientConfigPaths.GetEvidenceInfo(AppDomain appDomain,String exePath,ref String typeName)    在System.Configuration.ClientConfigPaths.GetTypeAndHashSuffix(AppDomain appDomain,String exePath)    在System.Configuration.ClientConfigPaths..ctor(String exePath,Boolean includeUserConfig)    在System.Configuration.ClientConfigPaths.GetPaths(String exePath,Boolean includeUserConfig)    在System.Configuration.ClientConfigurationHost.RequireCompleteInit(IInternalConfigRecord记录)    at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey,Boolean getLkg,Boolean checkPermission,Boolean getRuntimeObject,Boolean requestIsHere,ref Object result,ref Object resultRuntimeObject)    在System.Configuration.BaseConfigurationRecord.GetSection(String configKey)    在System.Configuration.ConfigurationManager.GetSection(String sectionName)    在NLog.Config.XmlLoggingConfiguration.get_AppConfig()    在NLog.LogFactory.get_Configuration()    在NLog.LogFactory.GetLogger(LoggerCacheKey cacheKey)    at NLog.LogFactory.GetLogger(String name)    在NLog.LogManager.GetCurrentClassLogger()

更新 当单元测试项目引用NSubstitute时会出现问题。因此,似乎存在一些Web API,NSubstitute和NLog的危险组合。

更新2: 发现什么扰乱了控制器中的Nlog。 在调用控制器方法之前,我为Thread.CurrentPrincipal设置了mocked principal:

var principal = Substitute.For<ClaimsPrincipal>();
principal.Identity.Returns(...);
Thread.CurrentPrincipal = principal;

如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

Castle程序集可以使用AllowPartiallyTrustedCallersAttribute标记,并使用2级安全透明度模型。

Level 2透明度导致AllowPartiallyTrustedCallers程序集中的所有方法默认情况下都变为透明,这可能是导致此异常的原因。

您可以尝试使用以下属性注释单元测试(和Class) - [SecuritySafeCritical]