Biztalk 2010自定义管道组件返回二进制文件
我创建了一个自定义管道组件,它将复杂的excel电子表格转换为XML。转换工作正常,我可以写出要检查的数据。但是,当我将此数据分配给inMsg的BodyPart.data部分或新消息时,总是会遇到路由失败。当我在管理控制台中查看消息时,正文似乎包含二进制数据(我假定是原始excel),而不是我分配的XML-请参见下面的屏幕截图。我遵循了许多教程和许多不同的方法,但总是得到相同的结果 我目前的代码是:Biztalk 2010自定义管道组件返回二进制文件,biztalk,custom-component,pipeline,biztalk-2010,Biztalk,Custom Component,Pipeline,Biztalk 2010,我创建了一个自定义管道组件,它将复杂的excel电子表格转换为XML。转换工作正常,我可以写出要检查的数据。但是,当我将此数据分配给inMsg的BodyPart.data部分或新消息时,总是会遇到路由失败。当我在管理控制台中查看消息时,正文似乎包含二进制数据(我假定是原始excel),而不是我分配的XML-请参见下面的屏幕截图。我遵循了许多教程和许多不同的方法,但总是得到相同的结果 我目前的代码是: public Microsoft.BizTalk.Message.Interop.IBaseM
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;
}
首先,我将围绕MemoryStream逻辑向组件添加更多日志记录—可能会将文件写入文件系统,以便确保Xml版本正确。您还可以附加到BizTalk进程并单步执行该组件的代码,这使得调试更加容易 我会尝试将MemoryStream的使用转换为更基本的自定义流,为您写入字节。在管道组件的BizTalk SDK示例中,有一些自定义流的示例。您必须自定义流示例,以便它只写入流。我可以发布一个例子。因此,请首先执行上述附加诊断
谢谢,以下是回复邮件的示例:
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;
}
谢谢,我已经完成了诊断,只是为了这篇文章删除了它们-我可以确认我正在写入数据的XML格式正确。