在.Net / C#中是为XmlSerializer.Serialize触发的OnSerializing事件

时间:2008-10-14 08:33:53

标签: c# .net

我想在序列化对象之前设置一些属性,但是因为它可以从多个位置序列化,有没有办法使用OnSerializing方法(或类似)进行Xml序列化 - 我的类很像这个 - 但On ......方法没有被调用......:

[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");
    }

2 个答案:

答案 0 :(得分:5)

不,XmlSerializer不支持此功能。如果您使用的是.NET 3.0或更高版本,请查看DataContractSerializer

答案 1 :(得分:2)

我试图破冰。请看一看。 创建一个名为MyXMLSerializer的类,如下所示:

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");
    }        
}

现在使用名称TotalRecall创建另一个类,并将MyXMLSerializer类继承到此类中,如下所示:

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();
    }
}

现在创建一个表单(我创建了一个Windows表单)。 在其上创建两个名称为Button1Button2的按钮(默认值)。我的完整表格代码是:

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();
    }
}

请在此复制粘贴期间的任何地方包含名称空间。