MethodAccessException when calling nlog LogManager.GetCurrentClassLogger()

550 views Asked by At

I'm getting an exception when I run a unit test on a controller in web project (ASP.NET web api). The exception is thrown when LogManager.GetCurrentClassLogger() of the controller is executed:

System.MethodAccessException: Attempt by method 'Castle.Proxies.ClaimsPrincipalProxy.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' to access method 'Castle.DynamicProxy.Internal.TypeUtil.Sort(System.Reflection.MemberInfo[])' failed

It results in TypeInitializationException in LogManager.GetCurrentClassLogger(). here is the call stack:

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

Update: The issue happens when the unit test project references NSubstitute. So, it seems like there some dangerous combination of Web API, NSubstitute and NLog.

Update 2: Found what upsets Nlog in Controller. Before calling controller method I set mocked principal for Thread.CurrentPrincipal:

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

How could this be fixed?

1

There are 1 answers

0
Mark Trinder On

The Castle assembly may be marked with the AllowPartiallyTrustedCallersAttribute, and that uses the level 2 security transparency model.

Level 2 transparency causes all methods in AllowPartiallyTrustedCallers assemblies to become security transparent by default, which may be the cause of this exception.

Can you try annotating your unit test (and Class) with the following attribute - [SecuritySafeCritical]