案例:
首先,我将解释配置文件的当前情况然后我会问我的问题: 我们有两个WCF双工服务(OrdinaryCustomerService,PremiumCustomerService)。这两个服务是相同的,只包含一个操作" DoOperation"并通过名为(ICustomerCallBack)的Callback回复客户端,该回调只包含一个操作(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不匹配,然后Match方法必须正常关闭连接并发送FaulException和Message,用户无法连接,这是我们的问题。 我将向您展示WebConfig用于托管App First然后我将解释该问题
主持应用程序的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>
问题:
如何使用FaultException进行过滤回复,而不是将消息转发给服务? 我试着用:
`OperationContext.Current.RequestContext.Reply(newreply);`
但RequestContext始终为null。
我也尝试使用
`OperationContext.Current.Channel`
和
`IClientChannel channel = OperationContext.Current.GetCallbackChannel<IClientChannel>()`
但我也无法将回复发送给客户。
请帮我解决这个问题,并提前感谢你。
答案 0 :(得分:0)
<强>答案:强>
我终于找到了这个问题的解决方案:
1-我们应该在我们调用的操作中放置一个DataContract而不是void。 2-在操作实现中我们可以返回空对象。 3-当我们调用操作时,我们必须将结果设置为变量我的意思是我们应该使用这个代码:
var mock = proxy.DoOperation();
而不是
proxy.DoOperation();
4-使用MessageInspector在路由之前检查即将发送的消息。
问候。