I need to replay some logs saved in JSON in .NET with WCF technology. The software use IClientMessageInspector to obtain the logs and save them in JSON afterwards. So, I need to get this logs and inject them again. To do this,I did something similar as I did when I obtains the logs. I did extend the WCF EndPoint and modify the message with new parameters. Here is the code :
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(record.Message.ToString());
var ms = new MemoryStream();
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(ms);
doc.WriteTo(writer);
writer.Flush();
ms.Position = 0;
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(ms, XmlDictionaryReaderQuotas.Max);
Message newReply = Message.CreateMessage(request.Version, null, reader);
newReply.Headers.CopyHeadersFrom(request);
request = newReply;
}
This function seems to have the right values. But, It can call many differents functions depending on the json file. To be able to go into that "BeforeSendRequest" method, I need to call a existing method for example :
m_MyService.XXX();
And because I modify it in "BeforeSendRequest", it shoudln't matter which function I'm calling here. But, it does return me the error :
System.ServiceModel.CommunicationException: Erreur lors de la désérialisation du corps du message de demande pour l'opération 'XXX'. OperationFormatter a rencontré un corps de Message non valide. Type de nœud 'Element' attendu avec le nom 'XXX' et l'espace de noms 'http://tempuri.org/'. Type de nœud 'Element' trouvé avec le nom 'YYY' et l'espace de noms 'http://tempuri.org/'. ---> System.Runtime.Serialization.SerializationException: OperationFormatter a rencontré un corps de Message non valide. Type de nœud 'Element' attendu avec le nom 'XXX' et l'espace de noms 'http://tempuri.org/'. Type de nœud 'Element' trouvé avec le nom 'YYY' et l'espace de noms 'http://tempuri.org/'.
à System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeRequest(XmlDictionaryReader reader, Object[] parameters)
à System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeRequest(Message message, Object[] parameters)
--- Fin de la trace de la pile d'exception interne ---
à System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeRequest(Message message, Object[] parameters)
à System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
à System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
à System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
à System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
It looks like it doesn't like when the method call isn't m_MyService.YYY();
I finally found the solution, hope it can help. I just had to modify the "action" in the header. So just add this line:
newReply.Headers.Action = "desiredcontent";