2

I need to deserialize an xml string into an internal c# class (.net core 5.0) but it seems like the default XmlSerializer doesn't support that as it can only deserialize xml string into a public class and its public properties. Is there any way around this limitation?

Example: https://dotnetfiddle.net/PkD8no

    using System;    
using System.IO;
using System.Xml.Serialization;

public class Program
{
    public static void Main()
    {
        var xml = "<?xml version=\"1.0\"?><SampleXml><SampleValue>sample</SampleValue></SampleXml>";

        var serializerForInternal = new XmlSerializer(typeof(InternalSampleXml));
        using (TextReader reader = new StringReader(xml))
        {
            var result = (InternalSampleXml)serializerForInternal.Deserialize(reader);
            Console.WriteLine(result.SampleValue);
        }
    }

    [System.SerializableAttribute()]
    internal class InternalSampleXml
    {
        internal string SampleValue{ get; set; }
    }
}
Rocky Balboa
  • 1,456
  • 2
  • 13
  • 21
  • 1
    There are dirty, hacky workarounds with two-pass compilation if you search for it. But if you have control over your internal class, you can decorate them with `[DataContract]` and `[DataMember]` and use [DataContractSerializer](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.datacontractserializer) – NPras Sep 10 '21 at 06:39
  • Thanks, I do have this control, I was just hoping to avoid that as I got hell lot of those classes already (part of legacy code). But it seems like DataContractSerializer will be the only way to go. Surprising, I admit. – Rocky Balboa Sep 10 '21 at 09:55
  • https://stackoverflow.com/a/1347212/5045688 – Alexander Petrov Sep 10 '21 at 15:00
  • @AlexanderPetrov thanks but this is not exactly the problem I described. I want to deserialize a string into a class with internal properties. Not the other way around. – Rocky Balboa Sep 13 '21 at 09:05
  • 1
    You can do it by generating an XML serialization assembly and using the InternalsVisibleTo attribute. This is the only way out if you want to apply XmlSerializer. Or switch to another serializer. – Alexander Petrov Sep 13 '21 at 12:27
  • 1
    If you do decide to go with a different serializer and need to make wholesale changes to your classes, you could probably Roslyn your way out of it. If you've never hooked into the compiler service, it's a fun rabbit hole to fall into. – NPras Sep 14 '21 at 23:02

1 Answers1

-1

Try to use the following sample code:

//required using System.Xml.Serialization;
[XmlRoot(ElementName = "SampleXml")]
public class InternalSampleXml
{

    [XmlElement(ElementName = "SampleValue")]
    public string SampleValue { get; set; }
}

and

//required using System.Xml.Serialization;
var xml = "<?xml version=\"1.0\"?><SampleXml><SampleValue>sample</SampleValue></SampleXml>";
var serializerForInternal = new XmlSerializer(typeof(InternalSampleXml));
using (TextReader reader = new StringReader(xml))
{
    var result = (InternalSampleXml)serializerForInternal.Deserialize(reader);
    Console.WriteLine(result.SampleValue);
}

The result as below:

enter image description here

Zhi Lv
  • 18,845
  • 1
  • 19
  • 30
  • 2
    All you did here is you added a public class named InternalSampleXml. But there's nothing internal in it. That doesn't make sense. – Rocky Balboa Sep 18 '21 at 08:06