【问题标题】:How to redirect WCF service calls to different operations based on the message content如何根据消息内容将 WCF 服务调用重定向到不同的操作
【发布时间】:2017-09-07 13:46:12
【问题描述】:

我在 WCF 服务中有一个操作(方法)。该操作有一个Json内容的参数。

[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
string NotifyAuditLineUpdated(AuditLineUpdatedModel notification);

对于这个参数 AuditLineUpdatedModel,我创建了一个预定义类,使用 DataContractAttributes 和 DataMemberAttributes 在反序列化过程中将 json 消息映射到对象。

但是,我有一个问题是客户端在 相同的字段名称 下有 不同的 Json 消息结构,我无法将所有案例组合在一个类中。换句话说,Json 消息有一个字段可以有不同的结构(不是值);因此,我试图将调用定向到不同的操作,这可以满足 Json 消息的多样性。

到目前为止,我发现 WCF 提供了服务级别的路由。我想知道是否可以在操作级别路由呼叫。换句话说,我有一个服务,其中包含两个不同参数类型的操作。是否可以捕获呼叫并检查消息内容,然后根据消息将呼叫引导到适当的操作?

为了您的信息,我尝试了 WCF 的 IDispatchMessageInspector(消息检查器功能)。我能够检查消息内容,但无法重定向或更改目标(到 uri)地址。 注意:此外,客户端服务无法针对两种不同的情况发送不同的 uri 请求。

【问题讨论】:

  • -“但我无法重定向或更改目的地(到 uri)” - 你能告诉我们为什么吗?如果您有另一个服务来处理新的消息类型,那么您当然应该能够为该服务创建一个新的服务客户端并使用新服务处理消息,然后将结果返回给原始服务。
  • 嗨@KosalaW,当我尝试执行以下行时,我收到错误 request.Headers.Add(MessageHeader.CreateHeader("To", "To" , ) );错误消息:信封版本“EnvelopeNone (schemas.microsoft.com/ws/2005/05/envelope/none)”;不支持添加消息头
  • 在下面查看我的答案。如果您还有其他问题,请告诉我。您不必为新服务添加标头。你只需要身体。
  • 答案已更新以显示 IDispatchMessageInspector 覆盖。

标签: c# json wcf wcf-routing idispatchmessageinspector


【解决方案1】:

这只是一个例子。代码是概念性的,你必须按照你想要的方式来实现它。

[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
string NotifyAuditLineUpdated(AuditLineUpdatedModel notification);

// you can host this somewhere else
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
string MyInternalService(AuditLineUpdatedModel1 notification);

public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel, InstanceContext instanceContext)
{
    object response;
    var isCallToMyInternalServiceRequired = VerificationMethod(request, out response);
    if(!isCallToMyInternalServiceRequired)
    {
        using(var client = new NotifyAuditLineUpdatedClient())
        {
            return client.NotifyAuditLineUpdated(response as AuditLineUpdatedModel);
        }
    }

    using(var client = new MyInternalServiceClient())
    {
        return client.MyInternalServiceClient(response as AuditLineUpdatedModel1);
    }
}   

private bool VerificationMethod(object notification, out object output)
{
    // your validation method.
}

【讨论】:

  • 我认为这是迄今为止我得到的最佳答案,但有一件事会让这个答案变得完整。使用此解决方案,我可以根据收到的请求在此处按名称调用我需要的任何方法,但是仍然会导致问题是 WCF 将调用原始客户端请求方法,我不能在这里完全偏离对另一种方法的调用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-31
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 2013-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多