Reputation: 9389
I work as a web developer with a web designer and we usually do like this : - I create the system , I generate some Xml files - the designer display the xml files with xslt
Nothing new.
My problem is that I use Xml Serialization to create my xml files, but I never use Deserialization. So I'd like to know if there is a way to avoid fix like these :
empty setter for my property
empty parameter-less constructor
implement IXmlSerializable and throw "notimplementedexception" on deserialization
do a copy of the class with public fields
Upvotes: 1
Views: 667
Reputation: 100248
class Preferences
{
private const string filePreferences = "preferences.xml";
public Preferences() { }
public static Preferences Load()
{
Preferences pref = null;
if (File.Exists(Preferences.FileFullPath))
{
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(Preferences));
using (var xmlReader = new System.Xml.XmlTextReader(Preferences.FileFullPath))
{
if (serializer.CanDeserialize(xmlReader))
{
pref = serializer.Deserialize(xmlReader) as Preferences;
}
}
}
return ((pref == null) ? new Preferences() : pref);
}
public void Save()
{
var preferencesFile = FileFullPath;
var preferencesFolder = Directory.GetParent(preferencesFile).FullName;
using (var fileStream = new FileStream(preferencesFile, FileMode.Create))
{
new System.Xml.Serialization.XmlSerializer(typeof(Preferences)).Serialize(fileStream, this);
}
}
}
Upvotes: 0
Reputation: 9011
Ok now i understand it. I don't think there can be any way to do it with XMLSerialization. XMLSerialization need these information to re-populate the object. It does not know that some user never deserialize data. You might have to write some code to generate XML for your objects.
Upvotes: 0
Reputation: 20157
I know you don't want to add a parameterless constructor nor setters, but that's the only way to go with using the XmlSerializer. The good news is the parameterless constructor can be private and the setters can be empty and serialization will work. See thus:
namespace Aesop.Dto
{
using System;
using System.Xml.Serialization;
/// <summary>
/// Represents an Organization ID/Name combination.
/// </summary>
[Serializable]
public sealed class Org
{
/// <summary>
/// The organization's name.
/// </summary>
private readonly string name;
/// <summary>
/// The organization's ID.
/// </summary>
private readonly int id;
/// <summary>
/// Initializes a new instance of the <see cref="Org"/> class.
/// </summary>
/// <param name="name">The organization's name.</param>
/// <param name="id">The organization's ID.</param>
public Org(string name, int id)
{
this.name = name;
this.id = id;
}
/// <summary>
/// Prevents a default instance of the <see cref="Org"/> class from
/// being created.
/// </summary>
private Org()
{
}
/// <summary>
/// Gets or sets the organization's name.
/// </summary>
/// <value>The organization's name.</value>
[XmlAttribute]
public string Name
{
get
{
return this.name;
}
set
{
}
}
/// <summary>
/// Gets or sets the organization's ID.
/// </summary>
/// <value>The organization's ID.</value>
[XmlAttribute]
public int ID
{
get
{
return this.id;
}
set
{
}
}
}
}
Upvotes: 0
Reputation: 3166
This article describes creating a custom XML serialiser so you can serialise private fields - it may take a little bit of moulding to the form that you want, but it's easier than it looks (honest!) and it's a good start to writing your own serialiser / deserialiser that will serialise exactly what you want - and doesn't care about parameterless constructors or writeable properties.
The only other solution I can think of is to make a wrapper class for every serialisable class - but I don't know how good that would be in the long run. I just get the impression it's not good.
Upvotes: 1
Reputation: 82096
Ok mis-read your question first time around! Pretty sure there is no way to avoid this. There has to be a parameterless constructor and you can't serialize readonly properties. I think your only other option is DataContractSerializer.
Upvotes: 4