【问题标题】:WCF REST Webservice : getting request data when the content is not xml validWCF REST Webservice:当内容不是xml有效时获取请求数据
【发布时间】:2015-09-17 12:58:38
【问题描述】:

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

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

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

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

有什么方法可以实现吗?

【问题讨论】:

  • WCF 可扩展性的一个很好的来源是MSDN blog of Carlos Figueira。您如何访问该消息?您是否尝试过实现自定义trace listener
  • @JérémieBertrand :我有一个自定义跟踪侦听器,用于将 WCF 跟踪重定向到我的滚动文件附加程序(由 log4Net 提供)。这不是问题,当我尝试记录请求时,我所拥有的只是消息不是 XML 有效的。无法检索无效 XML 消息的字符串表示来查看它有什么问题。
  • 解决方案可能是实现自定义Message Formatter,使用 WebContentFormat.Raw 应该保留消息。

标签: c# xml wcf rest


【解决方案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;
 }

我用来获取内容类型的Regex找到了here

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多