使用内置WCF路由器服务的URL路由接收错误
我想通过具有客户用户/密码安全策略的WCF路由器服务创建一个无扩展名(如果可能,无文件)的路由器端点。尝试通过SOAP消息路由时,我遇到以下错误异常:使用内置WCF路由器服务的URL路由接收错误,wcf,asp.net-4.5,wcf-routing,Wcf,Asp.net 4.5,Wcf Routing,我想通过具有客户用户/密码安全策略的WCF路由器服务创建一个无扩展名(如果可能,无文件)的路由器端点。尝试通过SOAP消息路由时,我遇到以下错误异常: <s:Fault> <faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</faultcode>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</faultcode>
<faultstring xml:lang="en-US">An unexpected failure occurred. Applications should not attempt to handle this error. For diagnostic purposes, this English message is associated with the failure: 'Shouldn't allocate SessionChannels if session-less and impersonating'.</faultstring>
<detail>
<ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<HelpLink i:nil="true"/>
<InnerException i:nil="true"/>
<Message>An unexpected failure occurred. Applications should not attempt to handle this error. For diagnostic purposes, this English message is associated with the failure: 'Shouldn't allocate SessionChannels if session-less and impersonating'.</Message>
<StackTrace>at System.Runtime.Fx.AssertAndThrow(String description)
at System.ServiceModel.Routing.RoutingChannelExtension.get_SessionChannels()
at System.ServiceModel.Routing.RoutingService.GetOrCreateClient[TContract](RoutingEndpointTrait endpointTrait, Boolean impersonating)
at System.ServiceModel.Routing.ProcessRequestAsyncResult`1.StartProcessing()
at System.ServiceModel.Routing.ProcessRequestAsyncResult`1..ctor(RoutingService service, Message message, AsyncCallback callback, Object state)
at System.ServiceModel.Routing.RoutingService.BeginProcessRequest[TContract](Message message, AsyncCallback callback, Object state)
at System.ServiceModel.Routing.RoutingService.System.ServiceModel.Routing.IRequestReplyRouter.BeginProcessRequest(Message message, AsyncCallback callback, Object state)
at AsyncInvokeBeginBeginProcessRequest(Object , Object[] , AsyncCallback , Object )
at System.ServiceModel.Dispatcher.AsyncMethodInvoker.InvokeBegin(Object instance, Object[] inputs, AsyncCallback callback, Object state)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace>
<Type>System.Runtime.Fx+InternalException</Type>
</ExceptionDetail>
</detail>
</s:Fault>
我的CustomServiceHostFactory代码:
public class CustomServiceHostFactory : ServiceHostFactory
{
protected override System.ServiceModel.ServiceHost CreateServiceHost(System.Type serviceType, System.Uri[] baseAddresses)
{
var host = base.CreateServiceHost(serviceType, baseAddresses);
var aspnet = host.Description.Behaviors.Find<AspNetCompatibilityRequirementsAttribute>();
if (aspnet == null)
{
aspnet = new AspNetCompatibilityRequirementsAttribute();
host.Description.Behaviors.Add(aspnet);
}
aspnet.RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed;
return host;
}
}
公共类CustomServiceHostFactory:ServiceHostFactory
{
受保护的覆盖System.ServiceModel.ServiceHost CreateServiceHost(System.Type serviceType,System.Uri[]基本地址)
{
var host=base.CreateServiceHost(serviceType,baseAddresses);
var aspnet=host.Description.Behaviors.Find();
如果(aspnet==null)
{
aspnet=新的AspNetCompatibilityRequirementsAttribute();
host.Description.Behaviors.Add(aspnet);
}
aspnet.RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed;
返回主机;
}
}
在web.config文件中,我定义了服务端点和行为:
<services>
<service name="System.ServiceModel.Routing.RoutingService" behaviorConfiguration="GatewayServiceBehavior">
<endpoint address="" binding="basicHttpBinding" contract="System.ServiceModel.Routing.IRequestReplyRouter" bindingConfiguration="GatewaySecureBinding" />
</service>
</services>
绑定和行为配置非常简单,只需一个简单的用户名/密码验证要求:
<binding name="GatewaySecureBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxBufferSize="65536" maxReceivedMessageSize="65536"
textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"
messageEncoding="Mtom">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
<behavior name="GatewayServiceBehavior">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CustomLib.CustomUsernameValidator, CustomLib"/>
</serviceCredentials>
<routing filterTableName="RoutingTable1" routeOnHeadersOnly="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
根据这篇博文---BasicHttpBinding和aspnet Compatibility在这种情况下不能很好地结合在一起。是的,我看到了一些关于这个问题的帖子,但没有明确的答案,因此我最终提出了这个问题。wsHttpBinding不是一个选项,因为它是一个面向外部的web服务。如果WCF路由服务在basicHttpBinding中不能正常工作,我会感到困惑。这会限制它的使用。为什么您觉得wsHttpBinding
不是一个选项?它可以与外部web服务一起使用。它支持SOAP 1.2和ws-*规范。如果您只需要支持SOAP 1.1,那么是的,您仅限于basicHttpBinding
(或滚动您自己的绑定)。wsHttpBinding被集成为默认使用Windows凭据以实现安全性。我需要能够匿名或通过用户名/密码从数据库路由。我可能不知道如何重新配置wsHttpBinding以支持这两种方案。
<binding name="GatewaySecureBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxBufferSize="65536" maxReceivedMessageSize="65536"
textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"
messageEncoding="Mtom">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
<behavior name="GatewayServiceBehavior">
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="CustomLib.CustomUsernameValidator, CustomLib"/>
</serviceCredentials>
<routing filterTableName="RoutingTable1" routeOnHeadersOnly="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>