Search code examples
wcf

After Enable IDispatchMessageFormatter I see nullable parameters in service


after add my formatter to operation behavior :

    public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
    {
        ServerMessageFormatter Formatter = new ServerMessageFormatter();
       dispatchOperation.Formatter = Formatter;
    }

In Formatter I have empty Deserialize method cause I want to use default behavior

 public void DeserializeRequest(System.ServiceModel.Channels.Message message, object[] parameters)
    {}

but In Serialize

    public System.ServiceModel.Channels.Message SerializeReply(System.ServiceModel.Channels.MessageVersion messageVersion, object[] parameters, object result)
            {
//some code
             }

Problem is that after enable this class, parameters in service method always was show as null, but in IDispatchMessageInspector class I see that parameters is send properly. I don't know why it's happening, I only add this message formatter code , it is possible that empty class for Deserialize causes this ?


Solution

  • When we are implementing IDispatchMessageFormatter interface usually we are not thinking that method DeserializeRequest is something important as it is not returning any data. This is misleading as method needs to do something.

    The easiest way to make parameters correctly passed is to use base DispatchMessageFormatter. Add it to the constructor.

    public class ResponseJsonFormatter : IDispatchMessageFormatter
    {
        IDispatchMessageFormatter basicDispatchMessageFormatter;
        OperationDescription Operation;
        public ResponseJsonFormatter(OperationDescription operation, IDispatchMessageFormatter inner)
        {
            this.Operation = operation;
            this.basicDispatchMessageFormatter = inner;
        }
    
        public void DeserializeRequest(Message message, object[] parameters)
        {
            basicDispatchMessageFormatter.DeserializeRequest(message, parameters);
        }
    
        public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
        {
            string json=Newtonsoft.Json.JsonConvert.SerializeObject(result);
            byte[] bytes = Encoding.UTF8.GetBytes(json);
            Message replyMessage = Message.CreateMessage(messageVersion, Operation.Messages[1].Action, new RawDataWriter(bytes));
            replyMessage.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Raw));
            return replyMessage;
        }
    }
    

    And initiate it in the behavior:

    public class ClientJsonDateFormatterBehavior : IOperationBehavior
    {
        public void AddBindingParameters(OperationDescription operationDescription, BindingParameterCollection bindingParameters)
        {
            // throw new NotImplementedException();
        }
    
        public void ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation)
        {
        }
    
        public void ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation)
        {
            dispatchOperation.Formatter = new ResponseJsonFormatter(operationDescription, dispatchOperation.Formatter);
        }
    
        public void Validate(OperationDescription operationDescription)
        {
            // throw new NotImplementedException();
        }
    }
    

    You can check the working example here in the github branch DateTimeFormatterWithParams