AddressFilter使用BizTalk REST适配器不匹配 - 为什么?

时间:2014-09-23 22:03:45

标签: wcf rest biztalk biztalk-2013

我正在使用WCF-WebHttp适配器尝试BizTalk 2013 REST功能。

我正在尝试模拟公开可用的REST API的行为 - Nordnet nExt API。特别是,我正在尝试模拟登录功能的行为:对/ [版本] /登录?service = [service]& auth = [blob]的空POST请求应返回带有一堆参数的响应主体其中包括会话令牌(此时响应并不重要,因为我还没有实现)

我已执行以下步骤:

  • 设置具有关联接收位置的接收端口
  • 将接收位置的适配器类型设置为WCF-WebHttp
  • 将端点地址设置为/1/login/Service1.svc(目前我正在推迟进行任何URL重写,只是在URL中引用强制性WCF服务定义文件)
  • 将HTTP方法和URL映射部分设置为:
<BtsHttpUrlMapping>
  <Operation Name="Login" Method="POST" Url="?service={SERVICE}&amp;auth={AUTH}"/>
  <Operation Name="Logout" Method="DELETE" Url="/{SESSION_KEY}"/>
</BtsHttpUrlMapping>
  • 将网址参数映射到某些相关的上下文属性
  • 使用BizTalk WCF配置向导在IIS中创建与上述参数匹配的应用程序

使用本地计算机中的PostMan向http:// localhost /1/login/Service1.svc?service=foo&auth=bar提交空POST会产生以下错误消息:

<Fault 
    xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
    <Code>
        <Value>Sender</Value>
        <Subcode>
            <Value 
                xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:DestinationUnreachable
            </Value>
        </Subcode>
    </Code>
    <Reason>
        <Text xml:lang="en-US">The message with To 'http://localhost/1/login/Service1.svc?service=foo&amp;auth=bar' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher.  Check that the sender and receiver's EndpointAddresses agree.</Text>
    </Reason>
</Fault>

为什么?

我的预感是它与空的POST主体有关,因为来自普通WCF服务的类似消息的其他一些问题表明该消息应该包含WS-Addressing'To'字段。但是,这是REST,而不是SOAP,因此该属性不相关。与引用此错误消息的大多数其他问题不同,我无法控制服务定义,因为BizTalk通过自定义主机工厂创建服务实例(这就是它所做的事情,与所有BizTalk WCF适配器一样)

如何让BizTalk-surfaced WCF服务识别空POST主体是否正确并将其路由到正确的端点?

编辑#1:

取得一些进展。将WebHttpBehaviour应用于接收位置会停止显示此错误消息,但是新的错误消息已取代它。现在对POST请求的响应是:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 
    xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Service</title>
        <style>BODY { color: #000000; background-color: white; font-family: Verdana; margin-left: 0px; margin-top: 0px; } #content { margin-left: 30px; font-size: .70em; padding-bottom: 2em; } A:link { color: #336699; font-weight: bold; text-decoration: underline; } A:visited { color: #6699cc; font-weight: bold; text-decoration: underline; } A:active { color: #336699; font-weight: bold; text-decoration: underline; } .heading1 { background-color: #003366; border-bottom: #336699 6px solid; color: #ffffff; font-family: Tahoma; font-size: 26px; font-weight: normal;margin: 0em 0em 10px -20px; padding-bottom: 8px; padding-left: 30px;padding-top: 16px;} pre { font-size:small; background-color: #e5e5cc; padding: 5px; font-family: Courier New; margin-top: 0px; border: 1px #f0f0e0 solid; white-space: pre-wrap; white-space: -pre-wrap; word-wrap: break-word; } table { border-collapse: collapse; border-spacing: 0px; font-family: Verdana;} table th { border-right: 2px white solid; border-bottom: 2px white solid; font-weight: bold; background-color: #cecf9c;} table td { border-right: 2px white solid; border-bottom: 2px white solid; background-color: #e5e5cc;}</style>
    </head>
    <body>
        <div id="content">
            <p class="heading1">Service</p>
            <p>Endpoint not found.</p>
        </div>
    </body>
</html>

......这本身几乎完全没用。

深入研究WCF跟踪日志,实际问题实际上是:

<TraceRecord Severity="Warning" Channel="Analytic" xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord">
<TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.TraceHandledException.aspx</TraceIdentifier>
<Description>Handling an exception. Exception details: System.InvalidOperationException: The incoming HTTP request's URI 'http://localhost/1/login/Service1.svc?service=foo&auth=bar' does not match any service operation.</Description>
<AppDomain>/LM/W3SVC/1/ROOT/1/login-2-130560354135646221</AppDomain>
<Exception>
<ExceptionType>System.InvalidOperationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The incoming HTTP request's URI 'http://localhost/1/login/Service1.svc?service=foo&amp;auth=bar' does not match any service operation.</Message>
<StackTrace>
at System.Runtime.Diagnostics.EtwDiagnosticTrace.WriteExceptionToTraceString(XmlTextWriter xml, Exception exception, Int32 remainingLength, Int32 remainingAllowedRecursionDepth)
at System.Runtime.Diagnostics.EtwDiagnosticTrace.ExceptionToTraceString(Exception exception, Int32 maxTraceStringLength)
at System.Runtime.Diagnostics.EtwDiagnosticTrace.GetSerializedPayload(Object source, TraceRecord traceRecord, Exception exception, Boolean getServiceReference)
at System.Runtime.TraceCore.HandledExceptionWarning(EtwDiagnosticTrace trace, String param0, Exception exception)
at System.ServiceModel.Dispatcher.HttpUnhandledOperationInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
at System.Runtime.ActionItem.DefaultActionItem.TraceAndInvoke()
at System.Runtime.ActionItem.CallbackHelper.InvokeWithoutContext(Object state)
at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<ExceptionString>System.InvalidOperationException: The incoming HTTP request's URI 'http://localhost/1/login/Service1.svc?service=foo&amp;auth=bar' does not match any service operation.</ExceptionString>
</Exception>
</TraceRecord>

所以问题仍然存在:为什么?

编辑#2:

我下载并安装了WCF-WebHttpAdapter Sample代码,看看它做了哪些不同的事情 - 令人失望的是它没有包含WebHttp接收位置,但它确实提示我尝试更多的东西。我试图复制已经存在的WSHttp接收位置,以便让该应用程序RESTful工作,我发现:

  • WebHttpBehaviour似乎是一只红鲱鱼
  • 删除查询参数并用simple / route / segments替换它们似乎按预期工作 - 我现在收到服务错误和挂起的消息,这表明消息正在通过WCF端点。

那么现在的问题是:WCF-WebHttp适配器是否正确支持查询参数,或者此功能是否已损坏?

1 个答案:

答案 0 :(得分:0)

我在这里可以看到两个问题。首先,您已在接收端口上配​​置GET并尝试POST。如果请求体是空的,您应该使用GET。如果要在配置中使用POST更改为POST。

其次,当BizTalk收到请求时,reqest正文将插入到邮件正文中。如果邮件正文为空,则BizTalk失败。您必须在接收端口上创建自定义管道,该管道根据业务流程期望的架构创建消息体。如果提升的变量是基于消息的,则必须将它们插入到消息中。

当邮件正文到位时,它应该按预期工作。