3

我想通过具有客户用户/密码安全策略的 WCF 路由器服务创建一个无扩展(如果可能,无文件)路由器端点。尝试通过它路由 SOAP 消息时,我收到以下错误异常:

<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&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)</StackTrace>
           <Type>System.Runtime.Fx+InternalException</Type>
        </ExceptionDetail>
     </detail>
  </s:Fault>

由于 URL 路由,我确实必须为服务主机启用 AspNetCompability。
以下是我遵循的步骤:
我已经在 RouteTable 中设置了一个带有适当 URL 路由规则的基本 .net 4.0 Web 应用程序:

routes.Add(new ServiceRoute("routerservice", new CustomServiceHostFactory(), typeof(System.ServiceModel.Routing.RoutingService)));` 

我的 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;
    }
}

在 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>  
4

0 回答 0