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