In .Net / C # è l’evento OnSerializing triggersto per XmlSerializer.Serialize

Voglio impostare alcuni attributi poco prima che l’object sia serializzato, ma dato che può essere serializzato da più posizioni, c’è un modo per farlo usando il metodo OnSerializing (o simile) per la serializzazione Xml – la mia class è in gran parte simile a questo – ma i metodi On … non vengono chiamati …:

[Serializable] [XmlRoot(ElementName = "ResponseDetails", IsNullable = false)] public class ResponseDetails { public ResponseDetails() {} [OnSerializing] internal void OnSerializingMethod(StreamingContext context) { logger.Info("Serializing response"); } [OnSerialized] internal void OnSerializedMethod(StreamingContext context) { logger.Info("Serialized response"); } [OnDeserialized] internal void OnDeserializedMethod(StreamingContext context) { logger.Info("Deserialized response"); } [OnDeserializing] internal void OnDeserializingMethod(StreamingContext context) { logger.Info("Deserializing response"); } 

No, XmlSerializer non supporta questo. Se usi .NET 3.0 o versioni successive, dai un’occhiata a DataContractSerializer .

Ho provato a rompere un po ‘di ghiaccio. Per favore guarda. Crea una class con il nome MyXMLSerializer questo modo:

 public class MyXMLSerializer { delegate void del_xmlSerializing(); del_xmlSerializing ds; delegate void del_xmlSerialized(System.IO.Stream stream, object o); AsyncCallback cb; del_xmlSerialized dd; delegate void del_xmlDeserializing(); del_xmlDeserializing dx; delegate object del_xmlDeserialized(System.IO.Stream stream); AsyncCallback db; del_xmlDeserialized xd; object FinalDeserializedObject = null; public MyXMLSerializer() { } public void Serialize(System.IO.Stream stream,object o,Type ClassType) { XmlSerializer xx = new XmlSerializer(ClassType); /* ON Serialization Beginning [ONSERIALIZING] */ ds = new del_xmlSerializing(OnXMLSerializing_Begin); IAsyncResult IAR_Begin = ds.BeginInvoke(null, null); ds.EndInvoke(IAR_Begin); /* ON Serialization Beginning [ONSERIALIZING] */ /* ON Serialization Completed ie [ONSERIALIZED] */ dd = new del_xmlSerialized(xx.Serialize); cb = new AsyncCallback(OnXMLSerializing_Completed); IAsyncResult IAR = dd.BeginInvoke(stream, o, cb, dd); // This Delay Is Important Otherwise The Next Line Of Code(From Where Serialize Is Called) // Gets Executed Prior To Conclusion Of EndInvoke, Consequently Throwing Exception. while (IAR.IsCompleted == false) Thread.Sleep(1); /* ON Serialization Completed ie [ONSERIALIZED] */ } public object Deserialize(System.IO.Stream stream,Type ClassType) { XmlSerializer xx = new XmlSerializer(ClassType); /* ON De-Serialization Beginning [ONDESERIALIZING] */ dx = new del_xmlDeserializing(OnXMLDeserializing_Begin); IAsyncResult IAR_Begin = dx.BeginInvoke(null, null); dx.EndInvoke(IAR_Begin); /* ON De-Serialization Beginning [ONDESERIALIZING] */ /* ON De-Serialization Completed [ONDESERIALIZED] */ xd = new del_xmlDeserialized(xx.Deserialize); db = new AsyncCallback(OnXMLDeserialization_Completed); IAsyncResult IAR = xd.BeginInvoke(stream, db, xd); // This Delay Is Important Otherwise The Next Line Of Code(From Where Serialize Is Called) // Gets Executed Prior To Conclusion Of EndInvoke ,Consequently Throwing Exception. while (IAR.IsCompleted == false) Thread.Sleep(1); return FinalDeserializedObject; /* ON De-Serialization Completed [ONDESERIALIZED] */ } private void OnXMLDeserialization_Completed(IAsyncResult I) { del_xmlDeserialized Clone = (del_xmlDeserialized)I.AsyncState; FinalDeserializedObject = Clone.EndInvoke(I); OnDeserialized(); } public virtual void OnSerialized() { MessageBox.Show("Serialization Completed"); } public virtual void OnDeserialized() { MessageBox.Show("Deserialization Completed"); } private void OnXMLSerializing_Completed(IAsyncResult I) { del_xmlSerialized Clone = (del_xmlSerialized)I.AsyncState; Clone.EndInvoke(I); OnSerialized(); } private void OnXMLDeserializing_Begin() { //Thread.Sleep(5000); OnDeserializing(); } public virtual void OnDeserializing() { MessageBox.Show("Beginning Deserialization"); } private void OnXMLSerializing_Begin() { //Thread.Sleep(5000); OnSerializing(); } public virtual void OnSerializing() { MessageBox.Show("Beginning Serialization"); } } 

Ora crea un’altra class con il nome TotalRecall ed eredita la class MyXMLSerializer in questa class in questo modo:

 public class TotalRecall:MyXMLSerializer { public override void OnSerialized() { MessageBox.Show("Yippeeee!!!!!,I Finally Managed To Wire [ONSERIALIZED] Event With XMLSerializer.My Code Upon XML Serialized[ONSERIALIZED] Goes Here.."); //base.OnSerialized(); } public override void OnSerializing() { MessageBox.Show("Yippeeee!!!!!,I Finally Managed To Wire [ONSERIALIZING] Event With XMLSerializer.My Code Upon XML Serializing[ONSERIALIZING] Goes Here.."); //base.OnSerializing(); } public override void OnDeserializing() { MessageBox.Show("Yes!!!!!,I Finally Managed To Wire [ONDESERIALIZING] Event With XMLSerializer.My Code Upon XML De-Serializing[ONDESERIALIZING] Goes Here.."); //base.OnDeserializing(); } public override void OnDeserialized() { MessageBox.Show("Yes!!!!!,I Finally Managed To Wire [ONDESERIALIZED] Event With XMLSerializer.My Code Upon XML De-Serialized[ONDESERIALIZED] Goes Here.."); //base.OnDeserialized(); } } 

Ora crea un modulo (ho creato un modulo di Windows). Crea due pulsanti con i nomi Button1 e Button2 (default). Il mio codice completo è:

 public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { TotalRecall xx = new TotalRecall(); Employee ee = new Employee(); FileStream fs = File.Create("sss.xml"); xx.Serialize(fs, ee, typeof(Employee)); fs.Close(); fs.Dispose(); } private void button2_Click(object sender, EventArgs e) { TotalRecall xx = new TotalRecall(); FileStream fs=File.OpenRead("sss.xml"); Employee ee = (Employee)xx.Deserialize(fs, typeof(Employee)); fs.Close(); fs.Dispose(); } } 

Si prega di includere spazi dei nomi ovunque mi sia perso durante questo copia-incolla.