Search code examples
c#jsonwcfwcf-routingidispatchmessageinspector

How to redirect WCF service calls to different operations based on the message content


I have an operation (method) in a WCF service. the operation has a parameter of Json content.

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

For this parameter AuditLineUpdatedModel, I have created a pre-definied class using DataContractAttributes and DataMemberAttributes to map the json message to an object during the deserialization.

However, I have a problem is that the client has a different Json message structures under same field name where I cannot combine all cases in a single class. In other words, the Json message has a field which could have different structure (not value); therefore, I'm trying to direct the call to a different operations which could satisfy the variety of the Json message.

So far I have found that WCF provides routing on the service level. I wonder if possible to route the calls on operation level. In other words, I have a single service with two operations of different parameter types. Is it possible to catch the call and check the message content, and then direct the call to a proper operation based on the message?

For your information, I have tried IDispatchMessageInspector (message inspector feature) of WCF. I was able to check the message content, but I am not able to redirect or change the destination (To uri) address. Note: In addition, the client service is not able to send different uri requests for the two different cases.


Solution

  • This is just an example. The code is conceptual and you will have to implement it the way you want.

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