当前位置:  开发笔记 > Android > 正文

BizTalk - 无法提升属性

如何解决《BizTalk-无法提升属性》经验,为你挑选了1个好方法。

使用BizTalk 2013r2 CU1,我为我的入站xsd创建了一个属性模式并部署了该应用程序.

当我使用标准的"xml接收"管道收到样本xml文档时,我可以看到所需的元素按预期被提升到上下文中.

然后,我创建了一个自定义管道,其中包含"Disassemble"阶段中的"XML反汇编程序"组件和"验证"阶段中的自定义组件.此自定义组件需要从上下文中读取提升的属性.但是,我发现当我将接收位置从"xml接收"管道切换到我的自定义管道时,我的属性不会被提升.我在自定义组件中使用以下代码来写出消息上下文中的项列表:

for (int x = 0; x < contextList.CountProperties; x++)
        {
            contextList.ReadAt(x, out name, out nspace);
            string value = contextList.Read(name, nspace).ToString();
            contextItems += "Name: " + name + " - " + "Namespace: " + nspace + " - " + value + "\r\n";
            if (name == _ContextPropertyName && nspace == _ContextPropertyNamespace)
                promotedPropFound = true;

        }
        Helpers.EventLogHelper eventHelper = new EventLogHelper();
        eventHelper.LogEvent(string.Format("Context items:{0}", contextItems));

        if (promotedPropFound == false)
            throw new Exception(string.Format("Unable to find promoted property with name[{0}] and namespace [{1}]", _ContextPropertyName, _ContextPropertyNamespace));

从事件日志中的输出我可以看到某些属性,如MessageType已被提升,但我的自定义属性没有.同样,如果我更改接收位置以使用标准的"xml接收"管道,那么该属性将从同一个xml文档的副本中提升(我通过停止订阅发送端口并从管理控制台查看上下文来检查此属性).

我发现这很奇怪,因为相同的"XML反汇编程序"组件存在于两个管道的相同"反汇编"阶段,具有相同(默认)配置.我开始认为2013r2CU1可能有问题 - 还有其他人遇到过同样的问题吗?



1> 小智..:

当XML Disassembler在您的自定义管道中执行时,无法保证您的属性已被提升.

传入消息作为流到达管道,数据指针设置在流的开头.
我认为XML反汇编程序不会读取流,它将它包装到某个流包装器类中,该类将在实际读取流时填充提升的属性.
必须至少读取一次流:当消息插入消息框时.因此可以保证属性将得到提升,但您不能假设它将在"Validate"阶段执行之前完成.

要确保这确实是您遇到的问题:在将消息导入消息框后检查您的消息.
如果您的推广财产在那里,我所描述的可能是正在发生的事情.

解决方案:

要使自定义管道组件正常工作,最好的解决方案就是像XML反汇编程序一样:获取传入流并将其包装到流包装器类中,该类可以触发您需要的任何功能.

程序集Microsoft.BizTalk.Streaming.dll有一些你可能感兴趣的包装类:ForwardOnlyEventingReadStream.
这个类有一个事件AfterLastReadEvent.您可以创建一些EventHandler并让它订阅此事件,以便仅在完全读取流后触发您的自定义功能,并且所有属性都已提升.

您的自定义组件将如下所示:

public IBaseMessage Execute(IPipelineContext context, IBaseMessage message)
{
    Stream stream = message.BodyPart.GetOriginalDataStream();
    CForwardOnlyEventingReadStream eventingReadStream = new CForwardOnlyEventingReadStream(stream);
    eventingReadStream.AfterLastReadEvent += new AfterLastReadEventHandler(DoSomething);

    message.BodyPart.Data = eventingReadStream; 
    return message;
}

private static void DoSomething(object src, EventArgs args)
{
}

解决问题的一种效率较低的方法是在"验证"阶段在自定义组件中完全读取流,并将流指针放回流的开头.

当您在管道组件中操作消息流时,Microsoft有一些指导原则:https: //msdn.microsoft.com/en-us/library/aa577699.aspx

更新:

OP需要将消息上下文传递给事件处理程序.可以使用Lambda表达式:

public IBaseMessage Execute(IPipelineContext context, IBaseMessage message)
{
    Stream stream = message.BodyPart.GetOriginalDataStream();
    CForwardOnlyEventingReadStream eventingReadStream = new CForwardOnlyEventingReadStream(stream);
    eventingReadStream.AfterLastReadEvent += new AfterLastReadEventHandler((src, args) => DoSomething(src, args, message.Context));

    message.BodyPart.Data = eventingReadStream; 
    return message;
}

private static void DoSomething(object src, EventArgs args, IBaseMessageContext messageContext)
{
}

这个SO问题可以引用附加参数的参考: Pass参数传递给EventHandler

推荐阅读
mobiledu2402852357
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有