Search code examples
c#.netxmlserializer

XmlSerializer behaves different with a property's private getter on .net framework and .net core


I've consumed a third party nuget package which supported .net core and .net framework (.net standard).

My project was a .net framework 4.62 project and when I've used that third party, I've received an exception from the XmlSerializer.

The problem was due to a private getter in a property.

Only public properties and fields can be serialized. Properties must have public accessors (get and set methods). If you need to serialize non-public data, use the BinaryFormatter class rather than XML serialization.

Full Source

After receiving that error, I tried to open a .net core 2.2 project, consumed the same third party nuget and saw that the same code worked there.

He is a small example of code that reproduces the issue:

public class Test
{
    public string TestProp { private get; set; }
}

// Exception on .net 462 and works on .net core 2.2
var serializer = XmlSerializer.FromTypes(new[] { typeof(Test) });

So, is this a bug on the .net core implementation or a feature? Is there anything I can do rather to support this on .net framework without forking the repo and fixing the code?


Solution

  • The "bug" here is that it fails at a different time; on net462 it fails during FromTypes; on netcoreapp2.2 and netcoreapp3.0, it fails during the Serialize, with:

    System.InvalidOperationException: There was an error generating the XML document. ---> System.MethodAccessException: Attempt by method 'Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterTest.Write2_Test(System.String, System.String, Test, Boolean, Boolean)' to access method 'Test.get_TestProp()' failed

    So ... it really isn't worth worrying about, IMO. There is no real feature difference, by which I mean: it isn't going to work either way. So just... don't do that?

    But: you could log it as a bug on github, and even submit a PR so that it fails earlier, if you really want.

    That said: if you add:

    public bool ShouldSerializeTestProp() => false;
    

    then it will actually work on netcoreapp2.2 and netcoreapp3.0, which is... nice I guess? And could even be considered a reason not to change the new behavior.