2012-03-14 9 views
0

複雑なExcelスプレッドシートをXMLに変換するカスタムパイプラインコンポーネントを作成しました。変換は正常に動作し、チェックするデータを書き出すことができます。しかし、このデータをInMsgのBodyPart.Data部分または新しいメッセージに割り当てると、私はいつもルーティングに失敗します。管理コンソールのメッセージを見ると、私が割り当てたXMLではなく、本文にバイナリデータが含まれているように見えます(私は元のExcelを想定しています)。以下のスクリーンショットを参照してください。私は数多くのチュートリアルやこれを行うさまざまな方法に従ってきましたが、常に同じ結果が得られます。Biztalk 2010カスタムパイプラインコンポーネントはバイナリを返します

Binary Returned

私の現在のコードは次のとおりです。

public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg) 
    { 


     //make sure we have something 
     if (inmsg == null || inmsg.BodyPart == null || inmsg.BodyPart.Data == null) 
     { 
      throw new ArgumentNullException("inmsg"); 
     } 

     IBaseMessagePart bodyPart = inmsg.BodyPart; 

     //create a temporary directory 
     const string tempDir = @"C:\test\excel"; 
     if (!Directory.Exists(tempDir)) 
     { 
      Directory.CreateDirectory(tempDir); 
     } 

     //get the input filename 
     string inputFileName = Convert.ToString(inmsg.Context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties")); 


     swTemp.WriteLine("inputFileName: " + inputFileName); 

     //set path to write excel file 
     string excelPath = tempDir + @"\" + Path.GetFileName(inputFileName); 
     swTemp.WriteLine("excelPath: " + excelPath); 

     //write the excel file to a temporary folder 
     bodyPart = inmsg.BodyPart; 
     Stream inboundStream = bodyPart.GetOriginalDataStream(); 
     Stream outFile = File.Create(excelPath); 
     inboundStream.CopyTo(outFile); 
     outFile.Close(); 

     //process excel file to return XML 
     var spreadsheet = new SpreadSheet(); 
     string strXmlOut = spreadsheet.ProcessWorkbook(excelPath); 

     //now build an XML doc to hold this data 
     XmlDocument xDoc = new XmlDocument(); 
     xDoc.LoadXml(strXmlOut); 

     XmlDocument finalMsg = new XmlDocument(); 
     XmlElement xEle; 
     xEle = finalMsg.CreateElement("ns0", "BizTalk_Test_Amey_Pipeline.textXML", 
             "http://tempuri.org/INT018_Workbook.xsd"); 
     finalMsg.AppendChild(xEle); 

     finalMsg.FirstChild.InnerXml = xDoc.FirstChild.InnerXml; 

     //write xml to memory stream 
     swTemp.WriteLine("Write xml to memory stream"); 
     MemoryStream streamXmlOut = new MemoryStream(); 
     finalMsg.Save(streamXmlOut); 
     streamXmlOut.Position = 0; 


     inmsg.BodyPart.Data = streamXmlOut; 
     pc.ResourceTracker.AddResource(streamXmlOut); 


     return inmsg; 
    } 

答えて

1

が戻ってメッセージを書くのサンプルです:

IBaseMessage Microsoft.BizTalk.Component.Interop.IComponent.Execute(IPipelineContext pContext, IBaseMessage pInMsg) 
     { 
      IBaseMessagePart bodyPart = pInMsg.BodyPart;   

if (bodyPart != null) 
      {  
using (Stream originalStrm = bodyPart.GetOriginalDataStream()) 
       { 
        byte[] changedMessage = ConvertToBytes(ret); 
        using (Stream strm = new AsciiStream(originalStrm, changedMessage, resManager)) 
        { 
         // Setup the custom stream to put it back in the message. 
         bodyPart.Data = strm; 
         pContext.ResourceTracker.AddResource(strm); 
        } 
       } 
      } 
    return pInMsg; 
} 

AsciiStreamはストリームを読み取るために、このようなメソッドを使用:

override public int Read(byte[] buffer, int offset, int count) 
     { 
      int ret = 0; 
      int bytesRead = 0; 

      byte[] FixedData = this.changedBytes; 

      if (FixedData != null) 
      { 
       bytesRead = count > (FixedData.Length - overallOffset) ? FixedData.Length - overallOffset : count; 
       Array.Copy(FixedData, overallOffset, buffer, offset, bytesRead); 


       if (FixedData.Length == (bytesRead + overallOffset)) 
        this.changedBytes = null; 

       // Increment the overall offset. 
       overallOffset += bytesRead; 
       offset += bytesRead; 
       count -= bytesRead; 
       ret += bytesRead; 
      } 

      return ret; 
     } 
+0

よろしくお願いします。ありがとうございました:) – RedEyedMonster

1

私が最初にすべてのMemoryStreamをロジックの周りにあなたのコンポーネントに多くのログを追加します - あなたが作ることができますので、おそらくファイルシステムにファイルを書き出しますXmlのバージョンが正しいことを確認してください。また、BizTalkプロセスに接続し、コンポーネントのコードをステップ実行することで、デバッグを大幅に簡単にすることができます。

私はMemoryStreamの使用をバイトを書き込むより基本的なカスタムストリームに切り替えようとします。パイプラインコンポーネントのBizTalk SDKサンプルには、カスタムストリームのいくつかの例があります。ストリームサンプルをカスタマイズするだけで、ストリームを書き込む必要があります。私は例を投稿することができます。したがって、最初に上記の追加の診断を行います。

おかげで、ここで

+0

おかげで、私はすでに持っています診断を行いました。この投稿のために削除されました。データに書き込むXMLが整形式であることを確認できます。 – RedEyedMonster