是否可以将消息错误从路由服务抛回 WCF 客户端

本文关键字:服务 WCF 客户端 路由 消息 错误 是否 | 更新日期: 2023-09-27 17:56:50

我的公司长期以来一直通过路由程序使用 ASPX 和 Windows 服务来管理连接,并允许我们的数据中心控制客户端建立连接的位置。

就在最近,我们开始使用MVC和WCF。是的,在2015年,我们只是转向这些事情。无论如何,他们在发布前一个月发现他们需要路由 WCF 流量,因为它位于防火墙外部或 DMZ 中。

我们将路由服务

放在网络内部,并在防火墙上打开一个端口,以便所有服务都可以在路由服务上受防火墙保护的通信。

我提供所有这些详细信息的唯一原因是因为这设置了对 WCF 服务配置方式的期望。我们使用证书进行安全和消息加密,因为我们必须加密发送消息。我们还添加了一个自定义标头,我们的路由器将使用该标头来路由消息。

我们的工作是路由器接收消息,检查标头,查找是否有终结点,转发消息,获取响应并将其发送回 WCF 服务。目前,这一切都运行良好。我们甚至可以从端点接收消息错误并将其发送回客户端。

我正在努力解决的是当故障源自路由器时,路由器如何将消息Fault发送回客户端。但是因为我的路由器不知道如何加密消息,所以这个故障被发回未加密。故障是诸如"端点无法访问"或"找不到端点"之类的东西。客户端收到以下错误,并显示错误:

An unsecured or incorrectly secured fault was received from the other party. 
See the inner FaultException for the fault code and detail.

内部例外是我在下面的代码中定义的。

Dim fe As FaultException = New FaultException(status)
Dim fault As MessageFault = fe.CreateMessageFault()
Dim msg = System.ServiceModel.Channels.Message.CreateMessage(getMessageVersion, fault, getAction)

getMessageVersion 将返回 Soap11 或 Soap12,具体取决于客户端getAction 从标头中的客户端请求返回操作。

有没有办法将客户端配置为接受这些错误,即使它们没有加密?我们希望将它们捕获为故障异常而不是异常,以将我们的故障异常逻辑放在一起处理一般故障。

任何帮助或见解将不胜感激。我们的新程序使用的是C#,我们的旧程序仍然是用VB编写的,所以把你熟悉的任何.Net代码扔给我,我会使用它。

是否可以将消息错误从路由服务抛回 WCF 客户端

以下是错误类:

    [Serializable]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "yourNamespace")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "yourNamespace")]
[System.Runtime.Serialization.DataContractAttribute(Namespace = "yourNamespace")]
public class CustomFault : ISerializable
{
    public string Message { get; set; }
}

以下是引用故障的接口和操作方法:

[ServiceContract(Namespace = "yourNamespace")]
public interface IService
{
    [FaultContractAttribute(
        typeof(CustomFault),
        Action = "", 
        Name = "Fault", 
        Namespace = "yourNamespace")]
    [System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults = true)]
    [OperationContract]
    Response Operation(Request request);
}

最后我是如何抛出错误的:

throw new FaultException<CustomFault>
             (
                 new GuiaMedicoFault("Custom Error description"),
                 new FaultReason("Error description")
             );

也许这段代码的某些部分可以帮助您或提供任何想法。

利用里卡多的信息,我能够缩小我正在做的事情。对此的实际答案完全取决于终结点配置。这取决于您的绑定。

我们不必更改路由器中的任何内容,但我们必须更改客户端,它看起来像这样。

    serviceClient.Endpoint.Binding = getWSHttpBinding();

那么应该是

    private CustomBinding getWSHttpBinding()
    {
        WSHttpBinding binding = new WSHttpBinding();
        binding.Security.Mode = SecurityMode.Message;
        binding.Security.Message.EstablishSecurityContext = false;
        binding.Security.Message.NegotiateServiceCredential = false;
        binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
        binding.MaxReceivedMessageSize = (1024 * 1024 * 10);
        BindingElementCollection elements = binding.CreateBindingElements();
        elements.Find<SecurityBindingElement>().EnableUnsecuredResponse = true;
        return new CustomBinding(elements);
    }

如果您看到此问题,此链接包含更多信息。 https://support.microsoft.com/en-us/kb/971493

我们可能只是将其作为异常而不是错误来处理。