WCF REST Web服务:在内容不是xml有效时获取请求数据

时间:2015-09-17 12:58:38

标签: c# xml wcf rest

我有一个WCF REST Web服务操作,该操作使用POST请求调用,该请求包含来自PHP网站的架构固定XML内容。 Web服务跟踪上有滚动文件日志,以便在处理请求时跟踪任何错误。

有时传入的消息无法处理,因为POST请求中的xml无效(例如,缺少end元素)。 要理解这个问题,我希望将请求中的源XML看作我日志中的原始字符串。

我确实试过实现IDispatchMessageInspector但是每当我尝试访问请求体时,我都会(正确地)得到XmlException。

System.ServiceModel.MessageLogging上添加监听器对于这种情况不起作用。

有任何方法可以达到这个目的吗?

1 个答案:

答案 0 :(得分:1)

我最终使用this post中描述的反射。

我的问题是我没有内部类型来正确执行此操作。有了ILSpy,我发现了我需要的类型。

我现在使用IDispatchMessageInspector进行日志记录,如下所示:

 public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
 {
     // Loggin incoming message
     log.WriteLine("Incoming message :");

     MessageEncoder encoder = OperationContext.Current.IncomingMessageProperties.Encoder;
     string contentType = encoder.ContentType;
     Match characterSetMatch = re.Match(contentType);

     if (!characterSetMatch.Success)
     {
         log.WriteLine("Failed to extract character set from request content type: " + contentType);
     }
     else
     {
         try
         {    
             Type bufferedMessageType = typeof(Message).Assembly.GetType("System.ServiceModel.Channels.BufferedMessage");
             Type bufferedMessageData = typeof(Message).Assembly.GetType("System.ServiceModel.Channels.BufferedMessageData");

             string characterSet = characterSetMatch.Groups[0].Value;

             object messageData = bufferedMessageType.InvokeMember("MessageData",
                           BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty,
                           null, request, null);

             object buffer = bufferedMessageData.InvokeMember("Buffer",
                                        BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty,
                                        null, messageData, null);


             ArraySegment<byte> arrayBuffer = (ArraySegment<byte>)buffer;
             Encoding encoding = Encoding.GetEncoding(characterSet);

             string requestMessage = encoding.GetString(arrayBuffer.Array, arrayBuffer.Offset, arrayBuffer.Count);

             log.WriteLine(requestMessage);
         }
         catch(Exception e)
         {
             log.WriteLine("Error in decoding incoming message");
             log.WriteException(e);
         }

     }

     return null;
 }

我用来获取内容类型的正则表达式here

Regex re = new Regex("(?<=charset=)[^;]*");