我有一个WCF REST Web服务操作,该操作使用POST请求调用,该请求包含来自PHP网站的架构固定XML内容。 Web服务跟踪上有滚动文件日志,以便在处理请求时跟踪任何错误。
有时传入的消息无法处理,因为POST请求中的xml无效(例如,缺少end元素)。 要理解这个问题,我希望将请求中的源XML看作我日志中的原始字符串。
我确实试过实现IDispatchMessageInspector
但是每当我尝试访问请求体时,我都会(正确地)得到XmlException。
在System.ServiceModel.MessageLogging
上添加监听器对于这种情况不起作用。
有任何方法可以达到这个目的吗?
答案 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=)[^;]*");