【问题标题】:Can I throw a message fault back to a WCF client from a routing service我可以从路由服务向 WCF 客户端抛出消息错误吗
【发布时间】:2015-06-17 14:53:01
【问题描述】:

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

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

我们将把路由服务放在网络中,并在防火墙上打开一个端口,这样所有服务都可以在路由服务上的防火墙保护下进行通信。

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

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

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

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 代码扔给我,我会使用它。

【问题讨论】:

  • 问几个问题可以更好地理解您的场景:1) 您是在使用 Wcf 路由还是实现自定义路由,例如接收 Message 对象的方法? 2)您的客户是否知道您正在抛出的自定义故障类或操作在您的路由应用程序的界面中标有 FaultContractAttribute?
  • 进行路由的服务实际上只是一个带有 HTTP 侦听器的 Windows 服务。希望我们可以通过同一个系统路由所有流量,这样我们就不必创建仍然使用相同路由服务的新端点。 2)我们只是抛出一个普遍的错误。路由器很可能最终有大约 50 多个 WCF 服务使用它,我们已经讨论过创建一个与客户端共享的故障,但目前决定我们只让路由器抛出一个通用故障。由 catch (FaultException ex) 处理
  • 有趣,我们这里也有类似的解决方案。当我们创建一个类时,我们可以正确地向客户端发送故障,该类具有 DataContract 属性,即 Message 的单个字符串属性。他们,在服务的运行中,我们用FaultContract装饰。因此,当发生任何异常时,我们会创建一个 FaultException 对象,并将其完美地序列化给客户端。如果需要,我可以提供示例代码。
  • 我肯定有兴趣看看可能的解决方案。

标签: c# .net web-services wcf encryption


【解决方案1】:

这里是故障类:

    [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; }
}

这里是引用Fault的界面和操作方法:

[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")
             );

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

【讨论】:

  • 您使用的是自定义端点还是 WSHttpBinding?我目前正在尝试使用 WSHttpBinding,我认为这可能是原因。看来我必须更改端点中的标志才能接受我的消息。 support.microsoft.com/en-us/kb/971493
  • 我使用 BasicHttpBinding 和 WebHttpBinding。几乎所有的服务都使用 Basic,一些特定的和其余的服务使用 WebHttp。为了使它们都使用相同的操作,我使用以下属性修饰了我的服务: [ServiceBehavior(ValidateMustUnderstand = false)] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
【解决方案2】:

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

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

    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

我们可能只是把它当作一个异常而不是一个错误来处理。

【讨论】:

    猜你喜欢
    • 2017-04-08
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多