Пользовательский конвейерный компонент Biztalk 2010 возвращает двоичный код - PullRequest
0 голосов
/ 14 марта 2012

Я создал пользовательский компонент конвейера, который преобразовывает сложную электронную таблицу Excel в XML. Преобразование работает нормально, и я могу выписать данные для проверки. Однако, когда я назначаю эти данные для части BodyPart.Data inMsg или нового сообщения, я всегда получаю ошибку маршрутизации. Когда я смотрю на сообщение в консоли администратора, кажется, что тело содержит двоичные данные (я полагаю, исходный Excel), а не XML, который я назначил - см. Снимок экрана ниже. Я следовал многочисленным учебникам и множеству разных способов сделать это, но всегда получал один и тот же результат.

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

Ответы [ 2 ]

1 голос
/ 15 марта 2012

Вот пример обратной записи сообщения:

    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;
        }
1 голос
/ 14 марта 2012

Прежде всего, я бы добавил дополнительные записи в ваш компонент с помощью логики MemoryStream - возможно, запишите файл в файловую систему, чтобы убедиться, что версия Xml верна. Вы также можете присоединиться к процессу BizTalk и пройтись по коду для компонента, что значительно упрощает отладку.

Я бы попробовал переключить использование MemoryStream на более простой пользовательский поток, который записывает байты для вас. В примерах BizTalk SDK для компонентов конвейера есть несколько примеров для пользовательского потока. Вы должны настроить образец потока так, чтобы он просто записывал поток. Я могу работать над публикацией примера. Так что сделайте дополнительную диагностику выше в первую очередь.

Спасибо

...