2014-09-01 35 views
1

服務器如何知道正在發送哪個序列化類?服務器如何檢測不同的序列化類? C#

客戶端:

public void SendCard(Card card) 
      { 
       var xmlSerializer = new XmlSerializer(typeof(Card)); 
       xmlSerializer.Serialize(s, card); 
      } 
public void SendStage(Stage stage) 
     { 
      var ser = new XmlSerializer(typeof(Stage)); 
      ser.Serialize(s, stage); 
     } 

服務器端:

private void Receive() 
     { 
      byte[] message = new byte[8192]; 
      int bytesread; 
      s = a_client.GetStream(); 
      while (true) 
      { 
       bytesread = 0; 
       try 
       { 
        //blocks until a message is read 
        bytesread = s.Read(message, 0, 8192); 
       } 
       catch (Exception z) { Console.WriteLine(z.Message); break; } 
       if (bytesread == 0) 
       { 
        // the client has disconnected 
        break; 
       } 
       //Message successfully received 
       ASCIIEncoding encoder = new ASCIIEncoding(); 
       string smessage = encoder.GetString(message, 0, bytesread); 
       //Somewhere Here needs to detect if message is serialized Card, Stage, or string 
      } 
     } 

像它需要一個良好的if語句或東西。並獲得錯誤,這篇文章主要是代碼..希望這個問題是可以解釋的。

+0

數據在發送之前是XML序列化的,所以它應該使用XmlSerializer.Deserialize進行XMLDeSerialized。 – 2014-09-01 07:07:24

+0

您是對的,但接收方如果知道客戶發送的是DeSerialize,Class Card或Class Stage,該怎麼辦? – 2014-09-01 07:21:27

+0

我可能有一個解決方案來思考一下。如果(smessage.Contains(「)」)和if(smessage.Contains(「」)) - 基本讀取正在發送的XML。 – 2014-09-01 15:32:10

回答

0

嘗試一個稍微不同的設計模式,其中您序列化的類總是相同的,但它包含兩個屬性:一個是您真正想要的類,序列化爲通用對象,另一個是包含類型的字符串你真正想要的課程。這樣服務器/客戶端通信總是相同的。

這種技術唯一需要注意的是,服務器和客戶端必須引用完全相同的類類型,因爲XML序列化/反序列化對象必須知道要提前序列化/反序列化的類類型。從你提出問題的方式來看,我認爲這是好的。

首先,一些輔助類。請注意XMLInclude的使用 - 這是警告。

[Serializable] 
public class card 
{ } 

[Serializable] 
public class stage 
{ } 

[Serializable] 
[XmlInclude(typeof(card)), XmlInclude(typeof(stage))] 
public class serializeHelper 
{ 
    public object Package { get; set; } 
    public string PackageType { get; set; } 

    public serializeHelper() { } // required for deserialization 

    public serializeHelper(object aPackage) 
    { 
     Package = aPackage; 
     PackageType = aPackage.GetType().FullName; 
    } 
} 

並顯示測試代碼以顯示其工作原理。這裏的關鍵技巧是Convert.ChangeType方法。

 // serialize a helper class containing a card 
     // use a local file for the example 

     string path = System.IO.Path.GetTempFileName(); 
     System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(path); 

     serializeHelper toBeSerialized = new serializeHelper(new card()); 
     XmlSerializer xmlSer = new XmlSerializer(typeof(serializeHelper)); 
     xmlSer.Serialize(streamWriter, toBeSerialized); 
     streamWriter.Close(); 

     // deserialize the helper class 

     System.IO.StreamReader streamReader = new System.IO.StreamReader(path); 
     XmlSerializer xmlDeser = new XmlSerializer(typeof(serializeHelper)); 
     serializeHelper wasDeserialized = (serializeHelper)(xmlDeser.Deserialize(streamReader)); 
     streamReader.Close(); 

     // get the type, and convert the package to the desired type 

     Type t = Type.GetType(wasDeserialized.PackageType); 
     object theFinalObject = Convert.ChangeType(wasDeserialized.Package, t); 

最後,如果你想在最終對象類型不能爲對象或變種,你必須找到做這會爲您的工作方式。 VB允許你在類型上使用Select Case,但是C#不能在Type上執行切換。

+0

完美!非常感謝,這太棒了。 – 2014-09-05 02:54:14

相關問題