自定义管道组件的问题
Issue with Custom Pipeline component
开发的自定义管道组件将传入流读取到文件夹中,并使用 Code Project
中已有的元数据通过 MessageBox.I am 仅传递一些元数据
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using System.IO;
namespace SendLargeFilesDecoder
{
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
[ComponentCategory(CategoryTypes.CATID_Decoder)]
[System.Runtime.InteropServices.Guid("53fd04d5-8337-42c2-99eb-32ac96d1105a")]
public class SendLargeFileDecoder : IBaseComponent,
IComponentUI,
IComponent,
IPersistPropertyBag
{
#region IBaseComponent
private const string _description = "Pipeline component used to save large files to disk";
private const string _name = "SendLargeFileDecoded";
private const string _version = "1.0.0.0";
public string Description
{
get { return _description; }
}
public string Name
{
get { return _name; }
}
public string Version
{
get { return _version; }
}
#endregion
#region IComponentUI
private IntPtr _icon = new IntPtr();
public IntPtr Icon
{
get { return _icon; }
}
public System.Collections.IEnumerator Validate(object projectSystem)
{
return null;
}
#endregion
#region IComponent
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
if (_largeFileLocation == null || _largeFileLocation.Length == 0)
_largeFileLocation = Path.GetTempPath();
if (_thresholdSize == null || _thresholdSize == 0)
_thresholdSize = 4096;
if (pInMsg.BodyPart.GetOriginalDataStream().Length > _thresholdSize)
{
Stream originalStream = pInMsg.BodyPart.GetOriginalDataStream();
string srcFileName = pInMsg.Context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties").ToString();
string largeFilePath = _largeFileLocation + System.IO.Path.GetFileName(srcFileName);
FileStream fs = new FileStream(largeFilePath, FileMode.Create);
// Write message to disk
byte[] buffer = new byte[1];
int bytesRead = originalStream.Read(buffer, 0, buffer.Length);
while (bytesRead != 0)
{
fs.Flush();
fs.Write(buffer, 0, buffer.Length);
bytesRead = originalStream.Read(buffer, 0, buffer.Length);
}
fs.Flush();
fs.Close();
// Create a small xml file
string xmlInfo = "<MsgInfo xmlns='http://SendLargeFiles'><LargeFilePath>" + largeFilePath + "</LargeFilePath></MsgInfo>";
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(xmlInfo);
MemoryStream ms = new MemoryStream(byteArray);
pInMsg.BodyPart.Data = ms;
}
return pInMsg;
}
#endregion
#region IPersistPropertyBag
private string _largeFileLocation;
private int _thresholdSize;
public string LargeFileLocation
{
get { return _largeFileLocation; }
set { _largeFileLocation = value; }
}
public int ThresholdSize
{
get { return _thresholdSize; }
set { _thresholdSize = value; }
}
public void GetClassID(out Guid classID)
{
classID = new Guid("CA47347C-010C-4B21-BFCB-22F153FA141F");
}
public void InitNew()
{
}
public void Load(IPropertyBag propertyBag, int errorLog)
{
object val1 = null;
object val2 = null;
try
{
propertyBag.Read("LargeFileLocation", out val1, 0);
propertyBag.Read("ThresholdSize", out val2, 0);
}
catch (ArgumentException)
{
}
catch (Exception ex)
{
throw new ApplicationException("Error reading PropertyBag: " + ex.Message);
}
if (val1 != null)
_largeFileLocation = (string)val1;
if (val2 != null)
_thresholdSize = (int)val2;
}
public void Save(IPropertyBag propertyBag, bool clearDirty, bool saveAllProperties)
{
object val1 = (object)_largeFileLocation;
propertyBag.Write("LargeFileLocation", ref val1);
object val2 = (object)_thresholdSize;
propertyBag.Write("ThresholdSize", ref val2);
}
#endregion
}
}
这里的问题是 LargeFileLocation 在接收管道中是可配置的。如果我第一次给出一个位置,例如 E:\ABC\,文件将发送到该位置。
但是如果我将位置更改为 E:\DEF\,文件仍会发送到之前的位置 E:\ABC。我试图创建一个新的 biztalk 应用程序删除旧的,但我仍然将文件放入旧位置 E:\ABC\ 不知道为什么。
您是否删除了 %BizTalkFolder%\Pipeline Components\ 中的 dll?
要刷新管道组件,您需要删除旧的dll file/remove VS 工具箱中的项目。然后重启VS,重新部署。
对于这个 LargeFileLocation ,我建议你把它做成 属性 这样你就可以配置它。
问题很可能与 属性 LargeFileLocation 的定义及其在 IPersist属性Bag 接口中的实现和使用有关。您可以尝试以下操作:
- 检查您在设计时是否在Pipeline中添加了E:\ABC路径。如果
是的,从那里删除它并第一次在管理控制台中设置
也看看它是如何表现的,我的感觉是它会采取临时路径
位置。
- 更改属性和 IPersist属性Bag 实现以使用 属性 和
public string LargeFileName {get;set;}
等声明,即没有局部变量 _largeFileName。
开发的自定义管道组件将传入流读取到文件夹中,并使用 Code Project
中已有的元数据通过 MessageBox.I am 仅传递一些元数据using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Component.Interop;
using System.IO;
namespace SendLargeFilesDecoder
{
[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]
[ComponentCategory(CategoryTypes.CATID_Decoder)]
[System.Runtime.InteropServices.Guid("53fd04d5-8337-42c2-99eb-32ac96d1105a")]
public class SendLargeFileDecoder : IBaseComponent,
IComponentUI,
IComponent,
IPersistPropertyBag
{
#region IBaseComponent
private const string _description = "Pipeline component used to save large files to disk";
private const string _name = "SendLargeFileDecoded";
private const string _version = "1.0.0.0";
public string Description
{
get { return _description; }
}
public string Name
{
get { return _name; }
}
public string Version
{
get { return _version; }
}
#endregion
#region IComponentUI
private IntPtr _icon = new IntPtr();
public IntPtr Icon
{
get { return _icon; }
}
public System.Collections.IEnumerator Validate(object projectSystem)
{
return null;
}
#endregion
#region IComponent
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
if (_largeFileLocation == null || _largeFileLocation.Length == 0)
_largeFileLocation = Path.GetTempPath();
if (_thresholdSize == null || _thresholdSize == 0)
_thresholdSize = 4096;
if (pInMsg.BodyPart.GetOriginalDataStream().Length > _thresholdSize)
{
Stream originalStream = pInMsg.BodyPart.GetOriginalDataStream();
string srcFileName = pInMsg.Context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties").ToString();
string largeFilePath = _largeFileLocation + System.IO.Path.GetFileName(srcFileName);
FileStream fs = new FileStream(largeFilePath, FileMode.Create);
// Write message to disk
byte[] buffer = new byte[1];
int bytesRead = originalStream.Read(buffer, 0, buffer.Length);
while (bytesRead != 0)
{
fs.Flush();
fs.Write(buffer, 0, buffer.Length);
bytesRead = originalStream.Read(buffer, 0, buffer.Length);
}
fs.Flush();
fs.Close();
// Create a small xml file
string xmlInfo = "<MsgInfo xmlns='http://SendLargeFiles'><LargeFilePath>" + largeFilePath + "</LargeFilePath></MsgInfo>";
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(xmlInfo);
MemoryStream ms = new MemoryStream(byteArray);
pInMsg.BodyPart.Data = ms;
}
return pInMsg;
}
#endregion
#region IPersistPropertyBag
private string _largeFileLocation;
private int _thresholdSize;
public string LargeFileLocation
{
get { return _largeFileLocation; }
set { _largeFileLocation = value; }
}
public int ThresholdSize
{
get { return _thresholdSize; }
set { _thresholdSize = value; }
}
public void GetClassID(out Guid classID)
{
classID = new Guid("CA47347C-010C-4B21-BFCB-22F153FA141F");
}
public void InitNew()
{
}
public void Load(IPropertyBag propertyBag, int errorLog)
{
object val1 = null;
object val2 = null;
try
{
propertyBag.Read("LargeFileLocation", out val1, 0);
propertyBag.Read("ThresholdSize", out val2, 0);
}
catch (ArgumentException)
{
}
catch (Exception ex)
{
throw new ApplicationException("Error reading PropertyBag: " + ex.Message);
}
if (val1 != null)
_largeFileLocation = (string)val1;
if (val2 != null)
_thresholdSize = (int)val2;
}
public void Save(IPropertyBag propertyBag, bool clearDirty, bool saveAllProperties)
{
object val1 = (object)_largeFileLocation;
propertyBag.Write("LargeFileLocation", ref val1);
object val2 = (object)_thresholdSize;
propertyBag.Write("ThresholdSize", ref val2);
}
#endregion
}
}
这里的问题是 LargeFileLocation 在接收管道中是可配置的。如果我第一次给出一个位置,例如 E:\ABC\,文件将发送到该位置。
但是如果我将位置更改为 E:\DEF\,文件仍会发送到之前的位置 E:\ABC。我试图创建一个新的 biztalk 应用程序删除旧的,但我仍然将文件放入旧位置 E:\ABC\ 不知道为什么。
您是否删除了 %BizTalkFolder%\Pipeline Components\ 中的 dll?
要刷新管道组件,您需要删除旧的dll file/remove VS 工具箱中的项目。然后重启VS,重新部署。
对于这个 LargeFileLocation ,我建议你把它做成 属性 这样你就可以配置它。
问题很可能与 属性 LargeFileLocation 的定义及其在 IPersist属性Bag 接口中的实现和使用有关。您可以尝试以下操作:
- 检查您在设计时是否在Pipeline中添加了E:\ABC路径。如果 是的,从那里删除它并第一次在管理控制台中设置 也看看它是如何表现的,我的感觉是它会采取临时路径 位置。
- 更改属性和 IPersist属性Bag 实现以使用 属性 和
public string LargeFileName {get;set;}
等声明,即没有局部变量 _largeFileName。