1

EDIT 2

log4net config:

<configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
.
.
.
  </configSections>

  <log4net>
    <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
      <file type="log4net.Util.PatternString" value="C:\Logs\somepath...\SPtoSFDC\" />
      <appendToFile value="true" />
      <rollingStyle value="Date" />
      <datePattern value="yyyy-MM-dd'.log'" />
      <maximumFileSize value="1024MB" />
      <maxSizeRollBackups value="50" />
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <staticLogFileName value="false" />
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="[%date{HH:mm:ss}] - %-5p - %c - %m%n" />
      </layout>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="RollingFileAppender" />
    </root>
  </log4net>

EDIT 1
Answering comments below:

Full error stack:

System.Configuration.ConfigurationErrorsException
  HResult=0x80131902
  Message=Configuration system failed to initialize
  Source=System.Configuration
  StackTrace:
   at System.Configuration.ConfigurationManager.PrepareConfigSystem()
   at System.Configuration.ConfigurationManager.GetSection(String sectionName)
   at System.Xml.Serialization.TempAssembly.get_UseLegacySerializerGeneration()
   at System.Xml.Serialization.TempAssembly..ctor(XmlMapping[] xmlMappings, Type[] types, String defaultNamespace, String location, Evidence evidence)
   at System.Xml.Serialization.XmlSerializer.GenerateTempAssembly(XmlMapping xmlMapping, Type type, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
   at System.Xml.Serialization.XmlSerializer..ctor(Type type)
   at Core.Base.XmlSerializerHelper.Serialize[T](T data) in D:\projects\SO.Job.SPtoSFDC\Core.Base\XmlSerializerHelper.cs:line 17
   at SPtoSFDC.UnitTests.When_sp_api.Should_xmlserialize() in D:\projects\SO.Job.SPtoSFDC\SPtoSFDC.UnitTests\When_sp_api.cs:line 38

  This exception was originally thrown at this call stack:
    [External Code]

Inner Exception 1:
SerializationException: Type is not resolved for member 'log4net.Util.PropertiesDictionary,log4net, Version=2.0.13.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a'.

I also move the code into a new class:

    public class XmlSerializerHelper : IXmlSerializerHelper
    {
        public string Serialize<T>(T data)
        {
            var ns = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });

            CallContext.FreeNamedDataSlot("log4net.Util.LogicalThreadContextProperties");

            var serializer = new XmlSerializer(typeof(T));

            serializer.UnknownNode += new XmlNodeEventHandler(serializer_UnknownNode);
            serializer.UnknownAttribute += new XmlAttributeEventHandler(serializer_UnknownAttribute);
            serializer.UnknownElement += new XmlElementEventHandler(serializer_UnknownElement);

            var writerSettings = new XmlWriterSettings
            {
                Indent = true,
                OmitXmlDeclaration = true
            };

            using (var streamWriter = new StringWriter())
            using (var xmlWriter = XmlWriter.Create(streamWriter, writerSettings))
            {
                serializer.Serialize(xmlWriter, data, ns);
                return streamWriter.ToString();
            }
        }

        private static void serializer_UnknownAttribute(object sender, XmlAttributeEventArgs e)
        {
            throw new System.NotImplementedException();
        }

        private static void serializer_UnknownNode(object sender, XmlNodeEventArgs e)
        {
            throw new System.NotImplementedException();
        }

        private static void serializer_UnknownElement(object sender, XmlElementEventArgs e)
        {
            throw new System.NotImplementedException();
        }
    }

The error still exist.
I already tried lowering the version of log4net but didn't work.

I've been looking around but fail to find any solution to this.
This is the test code:

        [Fact]
        public void Should_xmlserialize()
        {
            var data = new SampleXml
            {
                EmployeeId = 123456
            };

            var ns = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty });

            var serializer = new XmlSerializer(data.GetType());
            var writerSettings = new XmlWriterSettings
            {
                Indent = true,
                OmitXmlDeclaration = true
            };

            using (var streamWriter = new StringWriter())
            using (var xmlWriter = XmlWriter.Create(streamWriter, writerSettings))
            {
                serializer.Serialize(xmlWriter, data, ns);
                var g = streamWriter.ToString();
                var f = g;
            }

            Assert.True(true);
        }

And the class that I'm trying to serialize:

    [XmlRoot("request")]
    public class SampleXml
    {
        [XmlElement("employeeid")]
        public long EmployeeId { get; set; }

        [XmlElement("lastModifiedDate")]
        public string LastModifiedDate { get; set; }

        [XmlElement("isasofdate")]
        public bool IsAsOfDate { get; set; }
    }

enter image description here

log4net version is 2.0.13

TIA.

fiberOptics
  • 6,955
  • 25
  • 70
  • 105
  • This might be a common issue to others but I'm honestly clueless on how to fix this. I can't just remove log4net. Please help. – fiberOptics Jan 28 '22 at 13:55
  • Did you try this workaround? [https://stackoverflow.com/a/23664811](https://stackoverflow.com/a/23664811). You can also try to use `CallContext.FreeNamedDataSlot("log4net.Util.LogicalThreadContextProperties");` on line 40 right before initializing serializer. – Nouman Jan 31 '22 at 12:22
  • 2
    Might you please edit your question to share the full `ToString()` output of the exception, including exception type, message, traceback, and inner exception(s) if any, **as text**, rather than as a screen shot? It's requested here not to to use images for this purpose, see [*Discourage screenshots of code and/or errors*](https://meta.stackoverflow.com/a/307500) and [*Why not upload images of code on SO when asking a question*](https://meta.stackoverflow.com/a/285557) for why. – dbc Jan 31 '22 at 14:44
  • I know it might look very simple, but would using `typeof(SampleXml)` instead of `data.GetType()` solve it for you? – Hoshani Feb 03 '22 at 10:56
  • 1
    I assume you are using the classic .NET Framework, right? Which version? Did you already analyze whether [Fusion Log Viewer](https://learn.microsoft.com/en-us/dotnet/framework/tools/fuslogvw-exe-assembly-binding-log-viewer) shows something meaningful? – mu88 Feb 03 '22 at 16:04
  • @mu88 never used this before however I have no admin rights. I might use this in the future. – fiberOptics Feb 03 '22 at 16:34
  • Seems to be a configuration problem, maybe you should check the log4net configuration in your config file, if the section log4net is declared, if the version of log4net.dll is the right one in each log4net node that defines it, and if the log4net section is declared and every node needed for get the PropiertiesDictionary istance is avaiable. Maybe, it could be mandatory just the node with basic content in it, maybe for PropertiesDictionary is more complicated... Never used it so idk. Let me know. – Sycraw Feb 04 '22 at 10:07
  • 1
    just like @Sycraw says - this is most likely an issue with the configuration. can you share it? – itsho Feb 06 '22 at 13:28
  • Could you provide a sample repo on GitHub so that we could debug it? – mu88 Feb 07 '22 at 12:09
  • Hey guys thank you so much for your help. I decided to create another version of the project in .netcore 3.1 and the issue was gone. The amount of time that I had spent trying to fix the issue has taken more than the amount of time re-writing it in .netcore. – fiberOptics Feb 07 '22 at 16:38

1 Answers1

0

I've encountered the same issue couple of days ago at my workplace.

Where it happens?

It looks that is starts to happen since version 2.0.1 (this is nuget version of log4net, on apache site it corresponds to 1.2.12) on .NET Framework only

Why it happens?

There was a ticket where someone had the same issue during test runs. Which explains why it happens:

if your code puts some object of type declared in your or 3rd party assembly into the logical call context, e.g. using CallContext.LogicalSetData (in our case it was the usage of log4net LogicalThreadContext.Properties), when the executing thread is returned to the default app domain of testhost process, CLR tries to load that assembly there.

So apache`s log4net messes stuff in a CallContext if you'll use LogicalThreadContext.Properties

At apache`s release notes there was listed an issue LOG4NET-317 that was fixed in 1.2.12 version, it involves usage of a CallContext in the inner workings of LogicalThreadContext.

In a netstandard1.3 version, LogicalThreadContext uses AsyncLocal instead, so it explains why OP doesn't have this issue in a .net-core project.

How to reproduce?

Here is a small setup to reproduce this issue:

Dummy.csproj

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net471</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="log4net" Version="2.0.15" />
    </ItemGroup>
</Project>

Program.cs

using log4net;
using System;

public class Program
{
    public static void Main(string[] args)
    {
        // messing with CallContext via log4net.LogicalThreadContext
        LogicalThreadContext.Properties["dummy_property"] = 42;

        // create new domain and point it to a different folder
        // so it won't get to load dll's of parent domain
        AppDomainSetup domainSetup = new AppDomainSetup();
        domainSetup.ApplicationBase = "C:\\work\\temp\\";
        AppDomain domain = AppDomain.CreateDomain("AppDomainTestName", null, domainSetup);

        // try to get all assemblies of a new domain
        // here exception will be thrown.
        domain.GetAssemblies();
    }
}

Exception:

Unhandled Exception: System.Runtime.Serialization.SerializationException: Type is not resolved for member 'log4net.Util.PropertiesDictionary,log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a'.
   at System.AppDomain.GetAssemblies()
   at Program.Main(String[] args)

Possible workarounds

  • Upgrade project to .NET Core
  • Wrap problematic calls in a following construction:
    var log4netKey = "log4net.Util.LogicalThreadContextProperties";
    var log4netData = CallContext.LogicalGetData(log4netKey);
    // remove log4net data from call context, so there won't be
    // any problems with it
    CallContext.FreeNamedDataSlot(log4netKey);
    // problematic call
    // restore data
    CallContext.LogicalSetData(log4netKey, log4netData);
    
  • Put log4net dependency into GAC
Monsieur Merso
  • 1,459
  • 1
  • 15
  • 18