3

C# のメッセージのシリアル化に苦労しています。
次のようなコンストラクタを持つクラスがあります。

public ProposalRequestMessage(int imaNumber, int proposalId, bool trainingFlag, string firstSiteAddress,
                                  bool lastSiteFlag, string lastSiteAddress, int reasonCode,
                                  List<LaneSelection> theLaneSelections)
    {
        ImaNumber = imaNumber;
        ProposalId = proposalId;
        TrainingFlag = trainingFlag;
        FirstSiteAddress = firstSiteAddress;
        LastSiteFlag = lastSiteFlag;
        LastSiteAddress = lastSiteAddress;
        ReasonCode = reasonCode;
        laneSelections = new List<LaneSelection>(theLaneSelections);
    }

タイプ System.Collections.Generic.List のクラスの lanesSelections メンバー。ここで、LaneSelection は次のようになります。

public class LaneSelection
{
    public int LaneId { get; set; }
    public SignalAspect AspectCode { get; set; }

    public LaneSelection()
    {
    }
    public LaneSelection(int laneId, SignalAspect aspectCode)
    {
        LaneId = laneId;
        AspectCode = aspectCode;
    }
}  

SignalAspect は列挙型です。

次のように、MSMQ を介してこのクラスのインスタンスを含むメッセージを送信します。

System.Messaging.MessageQueue queue = new System.Messaging.MessageQueue(queuename);
        queue.Purge();

System.Messaging.Message msg = new System.Messaging.Message(theMessage, new System.Messaging.XmlMessageFormatter());
        queue.Send(msg);

いくつかのデバッグ ツールを使用して、結果の XML が次のようになっていることがわかりました。

<?xml version="1.0"?>
<IvtmMessage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
<MessageType>ProposalRequest</MessageType>  
<ProposalRequestMessage>    
    <ImaNumber>0</ImaNumber>    
    <ProposalId>2</ProposalId>    
    <TrainingFlag>false</TrainingFlag>    
    <FirstSiteAddress>M25/4690A</FirstSiteAddress>    
    <LastSiteFlag>false</LastSiteFlag>    
    <LastSiteAddress />    
    <ReasonCode>3</ReasonCode>    
    <LaneSelections>      
        <LaneSelection>        
            <LaneId>1</LaneId>        
            <AspectCode>Advisory20</AspectCode>      
        </LaneSelection>    
    </LaneSelections>  
</ProposalRequestMessage>  

次のように、反対側でメッセージを逆シリアル化します。

Queue = new System.Messaging.MessageQueue(queueName);
Queue.Formatter = new System.Messaging.XmlMessageFormatter(new Type[] { typeof(IvtmMessage) });
Queue.ReceiveCompleted += new System.Messaging.ReceiveCompletedEventHandler(Queue_ReceiveCompleted);
Queue.BeginReceive(new System.TimeSpan(0, 0, 0, 30));
...
System.Messaging.MessageQueue mq = (System.Messaging.MessageQueue)sender;
try
{    
     // End the asynchronous Receive operation.
     System.Messaging.Message m = mq.EndReceive(e.AsyncResult);

     IvtmMessage message = (IvtmMessage)m.Body;
     DecodeMessage(message);
}
catch (System.Messaging.MessageQueueException ex)
{
     string exception = ex.Message;
}
mq.BeginReceive();

return; 

クラスのすべてのメンバーは、laneSelections 要素を除いて正しく逆シリアル化されます。この要素は、XML では明らかに値を持ちますが、逆シリアル化されたメッセージでは null インスタンスに評価されます。

必死になって、リストをクラスに追加して、構築時に値1〜5を入力しようとしました。これが正しくシリアル化されている場合、問題は LaneSelection クラスにあることがわかりますが、そうでない場合は、List のシリアル化に問題があります。リストが正しくシリアル化されませんでした。

誰が何が問題なのか知っていますか?

4

2 に答える 2

2

おそらく [XmlInclude(typeof(LaneSelection))] 属性を ProposalRequestMessage クラスに追加する必要があります。

于 2013-02-12T08:02:47.510 に答える
1

二つのこと;

  1. IvtmMessage 宣言には「laneSelections」がありますが、シリアル化された XML は大文字の L を持つ「LaneSelections」です。
  2. 以下のコードのように、IvtmMessage クラスの LaneSelections プロパティに以下を追加してみましたか?

プロパティ定義;

 [XmlArray("LaneSelections"), XmlArrayElement("LaneSelection")]
 public List<LaneSelection> LaneSelections { get; set; }

プロパティとクラスに適切な Xml 属性がないと、プロパティ/オブジェクトの変換方法をシリアライザーに任せることになります。

于 2013-02-14T21:48:39.377 に答える