Bon, j'ai réussi à réaliser un petit testcase :
Voici la page :
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click"
Text="Serialisation avec attribut" />
</div>
<asp:Button ID="Button2" runat="server" onclick="Button2_Click"
Text="Serialisation avec XmlSerializer " />
<asp:Label ID="outLabel" runat="server" Text="Label"></asp:Label>
</form>
</body>
</html>
et son rendu dans le designer :

Voici le code associé aux boutons :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
using System.Diagnostics;
using System.Xml.Serialization;
using System.Text;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click( object sender, EventArgs e )
{
TopLevelClass c = new TopLevelClass("001");
MemoryStream memStream = new MemoryStream();
try {
SoapFormatter soapFormatter = new SoapFormatter();
soapFormatter.Serialize(memStream, c);
byte[] buff = memStream.GetBuffer();
string soapOutput = "";
foreach ( byte b in buff )
soapOutput += (char)b;
outLabel.Text = soapOutput.Replace("<", "<").Replace(">", ">").Replace("\n", "<br>");
}
finally {
memStream.Close();
}
}
protected void Button2_Click( object sender, EventArgs e )
{
TopLevelClass c = new TopLevelClass("001");
//TextWriter writer = new StringWriter();
XmlSerializer serializer = new XmlSerializer(c.GetType());
//serializer.Serialize(writer, c);
//writer.Close();
StringBuilder sb = new StringBuilder();
using ( StringWriter sw = new StringWriter(sb) ) {
serializer.Serialize(sw, c);
}
outLabel.Text = sb.ToString().Replace("<", "<").Replace(">", ">").Replace("\n", "<br>");
}
}
La classe que je veux sérialiser :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization;
[Serializable]
public class TopLevelClass
//: ISerializable
{
private TopLevelClass() { }
public TopLevelClass( string attValue )
{
stringAttr = attValue;
innerClassAttr = new InnerClass(145);
}
[Serializable]
public class InnerClass
{
private InnerClass() { }
public InnerClass( int i )
{
this.i = i;
}
int i ;
}
public string stringAttr ;
public InnerClass innerClassAttr;
//#region ISerializable Membres
//void ISerializable.GetObjectData( SerializationInfo info,
// StreamingContext context )
//{
// info.AddValue("huhu", "hoho");
//}
//#endregion
}
ERF : bon, finalement ça ne vaut pas le coût de pousser plus loin, j'ai juste oublié de mettre mon attribut d'innerClass en public... M'enfin ça semble complètement idiot cette limitation... Y a t il une justification ?
Donc en gros ça veut dire que je suis obligé de casser l'encapsulation de ma classe pour la sérialiser en XML.. ??

À noter que la méthode du bouton_1 sérialise tout, y compris les attributs non publics tels que l'attribut "i" de InnerClass ! Mais j'ai un peu la flemme de modifier le code existant dans le projet sur lequel je travaille... (effets de bords probables et je maîtrise mal le C# :/)
Du coup je pense que je vais passer mon attribut en public.... On n'a vraiment pas le choix avec un XMLSerializer ?
