1

I have an application runnin .NETFramework 4.6.1, using xml serialization for abstract classes and inherited types, with approach almost identical to this XML Serialization and Inherited Types, and it works great. But after porting application to UWP .NETCore I've encountered a strange exception. Here is a simple example to reproduce it.

public class ClassToSerialize
{
    [XmlElement(Type = typeof(CustomSerializer<AnotherOne>))]
    public AnotherOne anotherOne;

    public ClassToSerialize()
    {
    }
}

public abstract class AnotherOne
{
    public AnotherOne()
    {
    }
}

public class CustomSerializer<TType> : IXmlSerializable
{
    public CustomSerializer()
    {
    }

    public CustomSerializer(TType data)
    {
        m_data = data;
    }

    public static implicit operator CustomSerializer<TType>(TType data)
    {
        return data == null ? null : new CustomSerializer<TType>(data);
    }

    public static implicit operator TType(CustomSerializer<TType> obj)
    {
        return obj.m_data;
    }

    private TType m_data;

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
    }

    public void WriteXml(XmlWriter writer)
    {
    }
}

And creating XmlSerializer for this type

XmlSerializer sr = new XmlSerializer(typeof(ClassToSerialize));

causes exception

System.InvalidOperationException: TestApp.AnotherOne, TestApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null is not assignable from TestApp.CustomSerializer`1[[TestApp.AnotherOne, TestApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], TestApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.

Same code works in .netframework app. Did they changed something in .netcore or am i missing something?

Alex
  • 11
  • 2
  • Did you recompile on UWP? If not then you need to publish and install on UWP. Different versions of Net Library offsets into windows dlls are different so just moving executables doesn't work unless the version of Net Libraries are exactly the same. – jdweng Jun 14 '17 at 14:03
  • Yes I did, not using a bridge, the project was recreated as a new uniersal app project and compiled with .NETCore.UniversalWindowsPlatform 5.3.3 package. – Alex Jun 14 '17 at 14:13
  • I'm having the exact same problem. Did you find a solution for this? – wexman Mar 01 '19 at 14:45
  • @wexman yeah, kind of. I got rid of atribute [XmlElement(Type = typeof(CustomSerializer))], because it was the reason of the exception, and reworked my serialization system. When creating XmlSerializer, you can provide list of additional types for serializer, so using reflection i recursively collected all nested types in class i want to serialize, and passed them to XmlSerializer constructor – Alex Mar 02 '19 at 17:31
  • @Alex thanks, but I'm afraid that is not possible for me. I have actually now opened an issue at https://github.com/dotnet/corefx/issues/35691, but it doesn't seem to get picked up somehow. Maybe you want to leave a comment there... – wexman Mar 19 '19 at 08:25

3 Answers3

1

Your issue linked with type that represented serialization type. For universal App their must be derived from (as I can see) For example:

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        XmlSerializer sr = new XmlSerializer(typeof(ClassToSerialize));
        var demo = new DemoChild();
        var ser = new ClassToSerialize {anotherOne = demo};
        var stream = new MemoryStream();
        sr.Serialize(stream, ser);
    }
}

public class ClassToSerialize
{
    [XmlElement(Type = typeof(DemoChild))]
    public AnotherOne anotherOne;

    public ClassToSerialize()
    {
    }
}

public abstract class AnotherOne : IXmlSerializable
{
    protected AnotherOne()
    {
    }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
    }

    public void WriteXml(XmlWriter writer)
    {
    }
}

public class DemoChild: AnotherOne
{
}

Using generic serializer is important for you? I've tested on universal App unit test and all work correctly.

P.s. Type - The of an object derived from the member's type. From documentation

0

Use XAML serializer:

nuget> Install-Package Portable.Xaml

public class ClassToSerialize
{
    public AnotherOne anotherOne { get; set; }

    public ClassToSerialize()
    {
    }
}


public abstract class AnotherOne
{
    public AnotherOne()
    {
    }
}

public class ContainerOne : AnotherOne
{
    public uint placeholder = 0xdeadcafe;
}



public void Test()
{
    ClassToSerialize obj = new ClassToSerialize();
    obj.anotherOne = new ContainerOne();

    //or FileStream..
    using (MemoryStream ms = new MemoryStream())
    {
        Portable.Xaml.XamlServices.Save(ms, obj);
        ms.Seek(0, SeekOrigin.Begin);
        ClassToSerialize obj2 = Portable.Xaml.XamlServices.Load(ms) as ClassToSerialize;
    }
}
Hema
  • 988
  • 1
  • 16
  • 38
0

Try downloading System.Xml.XmlSerializer from Nuget. I think it is developed in .NETStandard here lists all versions of .NET Standard and the platforms supported

LP13
  • 30,567
  • 53
  • 217
  • 400