简体   繁体   中英

C# generate XML for non-serializable properties

I'm having a lot of classes that I would like to export as XML for other applications to consume. The properties I want to export don't have a setter and the classes don't have a constructor without properties since I don't want this behaviour in my code. Therefore, it seems I can't use (XML) serialization on these classes and properties, even though I do want to export it into XML. I don't need deserialization though, as the serialization to XML is meant to be export-only.

I have tried XML serialization, but it appears this really only supports classes that can be used in both directions (serialization AND deserialization), which makes my classes not applicable. https://docs.microsoft.com/en-us/dotnet/standard/serialization/introducing-xml-serialization

Obviously, I could make serializable versions of each class, but doing this by hand would need to me to check manually after any updates of the original classes that I have updated the serializable classes. Additionally, I would need to write for every class, the code to transform is to its serializable version.

Is there a way to use the strength of XML serialization which takes care of all fuzz about XML, without needing the classes to be deserializable? Or do you have any other suggestions for easy ways to export XML for these classes and properties?

There's a really simple bit of guidance that applies to virtually every serializer , regardless of format (xml, json, protobuf, etc), implementation details, etc:

  • if your type model happens to be a 1:1 fit for the serializer, great! use it!
  • otherwise, don't try ; create a completely separate model that is purely for serialization ; the shape and behavior should be exactly what the serializer needs to get the result you want; then map between the two models (your domain model, and the serialization model) as needed

There is a caveat around "many serializers allow a custom serializer API", but in my experience, it usually isn't worth the pain , and switching to a separate serialization model is a better idea. This applies especially in the case of XmlSerializer , since IXmlSerializable is virtually impossible to implement absolutely correctly manually.

So; to be explicit here; if the problem is that your type lacks the correct constuctors and property setters to work with XmlSerializer : create a new model that has those things , and just shim between them.

The DataContractSerializer can serialize classes without a default constructor.

You will have to mark the class with DataContractAttribute in order to do so. Also, the properties to serialize need setters. The setters may be private, but the setter does have to exist:

[DataContract] // Need this to serialize classes without default constructor.
public class Person
{
    public Person(string name, DateTime dob)
    {
        this.Name = name;
        this.DateOfBirth = dob;
    }

    [DataMember] // Need this to serialize this property
    public string Name { get; private set; } // Need setter for serializer to work

    [DataMember]
    public DateTime DateOfBirth { get; private set; }
}

Usage:

var person = new Person("Jesse de Wit", new DateTime(1988, 5, 27));
var serializer = new DataContractSerializer(typeof(Person));
using (var stream = new MemoryStream())
{
    serializer.WriteObject(stream, person);
}

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