我在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;
如何解决这个问题?
答案 0 :(得分:0)
Castle程序集可以使用AllowPartiallyTrustedCallersAttribute标记,并使用2级安全透明度模型。
Level 2透明度导致AllowPartiallyTrustedCallers程序集中的所有方法默认情况下都变为透明,这可能是导致此异常的原因。
您可以尝试使用以下属性注释单元测试(和Class) - [SecuritySafeCritical]