简体   繁体   中英

DataContract serialization of an inherited type into a base type

I'm trying to serialize class B as an instance of ita base class A . The DataContractSerializer won't allow me to do that.

An example failing the serialization is as follows:

class Program
{
    [DataContract]
    public class A
    {
        public int Id { get; set; }
    }

    [DataContract]
    public class B : A
    {

    }


    static void Main(string[] args)
    {
        A instance = new B { Id = 42 };

        var dataContractSerializer = new DataContractSerializer(typeof(A));
        var xmlOutput = new StringBuilder();
        using (var writer = XmlWriter.Create(xmlOutput))
        {
            dataContractSerializer.WriteObject(writer, instance);
        }

    }
}

I know that the issue is easily resolved by added the KnownTypes attribute. However I want to keep the class B hidden from the project (not add a reference).

Is it at all possible to achieve what I want? I tried the XmlSerializer but it gave me the same issue (it added the full instance type name in the XML) and is much more clunkier to use.

[DataContract(Name="YouCannotSeeMyName")]
[KnownTypes(typeof(B))]
public class B : A

And you will get

<A itype="YouCannotSeeMyName">
  ...
</A>

I'm pretty sure that you can't hide portions of the contract. This is akin to dealing with a web service where the contract has to be honored for each end to understand how and what to seriialize/deserialize.

In addition you can pass the B type within the DataContractSerializer versus using the attribute.

    class Program
    {
        [DataContract]
        public class A
        {
            public int Id { get; set; }
        }

        [DataContract]
        public class B : A
        {

        }

        static void Main(string[] args)
        {
            A instance = new B { Id = 42 };

            var dataContractSerializer = new DataContractSerializer(typeof(A), new List<Type>() { typeof(B) });
            var xmlOutput = new StringBuilder();
            using (var writer = XmlWriter.Create(xmlOutput))
            {
                dataContractSerializer.WriteObject(writer, instance);
            }

        }
    }

Which will give you...

<Program.A xmlns:i="http://www.w3.org/2001/XMLSchema-instance" i:type="Program.B"
xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication1" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM