C# 如何使路由服务自定义筛选器回复FaultException?

C# 如何使路由服务自定义筛选器回复FaultException?,c#,wcf,routing,C#,Wcf,Routing,案例: 首先,我将解释配置文件的当前情况,然后我将提出我的问题: 我们有两个WCF双工服务(普通客户服务、PremiumCustomerService)。这两个服务是相同的,只包含一个操作“DoOperation”,并通过名为(ICCustomerCallback)的回调(只包含一个操作(Notify)回复客户端。 源代码: [ServiceContract(CallbackContract = typeof (ICustomerCallBack))] public interface ICus

案例:

首先,我将解释配置文件的当前情况,然后我将提出我的问题: 我们有两个WCF双工服务(普通客户服务、PremiumCustomerService)。这两个服务是相同的,只包含一个操作“DoOperation”,并通过名为(ICCustomerCallback)的回调(只包含一个操作(Notify)回复客户端。 源代码:

[ServiceContract(CallbackContract = typeof (ICustomerCallBack))]
public interface ICustomer
{

    [OperationContract] 
    [FaultContract(typeof (FaultException))]
    void DoOperation();

}

public interface ICustomerCallBack
{

    [OperationContract(IsOneWay = true)]
    void Notify(String message);

}
我们还有路由服务(CustomerService),它将传入的消息转发到OrdinaryCustomerService或PremiumCustomerService,此选择基于路由表中的自定义筛选器。路由服务有两个自定义筛选器HiBillingFilter和LowBillingFilter 过滤器检查呼叫者标识是否与存储的标识匹配,然后检查呼叫者等级,有三个选项: 首先:呼叫者ID与存储匹配,排名与存储匹配,然后筛选器必须将消息转发到指定的服务器。 第二:呼叫者ID与存储的匹配,但排名不匹配,则筛选器必须检查下一个筛选器 第三:呼叫者ID不匹配,那么匹配方法必须优雅地关闭连接,并发送FaulException,其中包含用户无法连接的消息,这就是我们的问题。 我将向您展示托管应用程序的网络配置,然后我将解释这个问题

托管应用程序的WebConfig是:

  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpBinding_ICustomer" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" receiveTimeout="00:10:00" sendTimeout="00:10:00">
          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://localhost:808/OrdinaryCustomerService/" binding="netTcpBinding" contract="*" name="CustomerServiceLibrary_OrdinaryCustomerService" />
      <endpoint address="net.tcp://localhost:807/PremiumCustomerService" binding="netTcpBinding"  contract="*" name="CustomerServiceLibrary_PremiumCustomerService" />
    </client>
    <services>
      <service name="OrdinaryCustomerService.OrdinaryCustomerService" behaviorConfiguration="normalServiceBehavior" >
        <endpoint address="" binding="netTcpBinding" contract="CustomerContract.ICustomer" bindingConfiguration="NetTcpBinding_ICustomer">
          <identity>
            <dns value="xxx" />
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:808/OrdinaryCustomerService/" />
          </baseAddresses>
        </host>
      </service>
      <service name="PremiumCustomerService.PremiumCustomerService" behaviorConfiguration="normalServiceBehavior" >
        <endpoint address="" binding="netTcpBinding" contract="CustomerContract.ICustomer" bindingConfiguration="NetTcpBinding_ICustomer">
          <identity>
            <dns value="xxx" />
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:807/PremiumCustomerService" />
          </baseAddresses>
        </host>
      </service>
      <service behaviorConfiguration="RoutingServiceBehavior" name="System.ServiceModel.Routing.RoutingService">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:809/CustomerService/" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="netTcpBinding" contract="System.ServiceModel.Routing.IDuplexSessionRouter"  name="RoutingServiceEndpoint" bindingConfiguration="NetTcpBinding_ICustomer">
          <identity>
            <dns value="xxx" />
          </identity>
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="RoutingServiceBehavior">
          <serviceDebug includeExceptionDetailInFaults="true" />
          <routing filterTableName="routingRules" routeOnHeadersOnly="False"  />
        </behavior>
        <behavior name="normalServiceBehavior">
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <routing>
       <namespaceTable>
         <add prefix="cc" namespace="http://schemas.datacontract.org/2004/07/CustomerContract" />
      </namespaceTable> 
      <filters>
        <filter name="HiBillingFilter" filterType="Custom" customType="CustomerService.HiBillingFilter, CustomerService"/>
        <filter name="LowBillingFilter" filterType="Custom" customType="CustomerService.LowBillingFilter, CustomerService"/>
        <filter name="MatchAll" filterType="MatchAll" />
      </filters>
      <filterTables>
        <filterTable name="routingRules">
          <add filterName="HiBillingFilter" endpointName="CustomerServiceLibrary_PremiumCustomerService" priority="2"/>
          <add filterName="LowBillingFilter" endpointName="CustomerServiceLibrary_OrdinaryCustomerService" priority="1"/>
          <add filterName="MatchAll" endpointName="CustomerServiceLibrary_OrdinaryCustomerService" priority="0" />
        </filterTable>
      </filterTables>
      <backupLists>
        <backupList name="CustomerBackupList">
          <add endpointName="CustomerServiceLibrary_OrdinaryCustomerService" />
        </backupList>
      </backupLists>
    </routing>
  </system.serviceModel>
但是RequestContext总是空的

我也试着用

`OperationContext.Current.Channel`

`IClientChannel=OperationContext.Current.GetCallbackChannel()`
但我也无法将回复发送给客户


请帮我解决这个问题,并提前向您表示感谢。

回答:

我终于找到了这个问题的解决方案:

1-我们应该在我们称之为的操作中使用DataContract而不是void。 2-在操作实现中,我们可以返回空对象。 3-调用操作时,我们必须将结果设置为变量,我的意思是我们应该使用以下代码:

var mock = proxy.DoOperation();
而不是

proxy.DoOperation();
4-在发送消息之前,使用MessageInspector检查即将发送的消息

问候

var mock = proxy.DoOperation();
proxy.DoOperation();