如何解决WCF消息记录-使用XPath查询添加过滤器
| 我有一份带有以下合同的WCF服务:[ServiceContract(Namespace=\"http://myNamespace.org/\")]
public interface IMyService
{
[OperationContract]
string Invert(string s);
[OperationContract]
string ToUpper(string s);
}
客户调用两种方法methods1ѭ和ToUpper
。想象一下我想使用消息日志记录,但是我感兴趣的唯一方法是ToUpper
,因为另一种方法被大量使用,并且记录所有消息会破坏日志;)
在这里,我阅读了如何过滤写入日志的消息。但是我肯定做错了,因为我的日志仍然是空的...我的配置看起来像这样
<system.serviceModel>
...
<diagnostics>
<messageLogging logEntireMessage=\"true\" logMessagesAtServiceLevel=\"false\" logMalformedMessages=\"true\" logMessagesAtTransportLevel=\"true\">
<filters>
<add xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:a=\"http://www.w3.org/2005/08/addressing\">/soap:Envelope/soap:Header/a:Action[starts-with(text(),\'http://myNamespace.org/IMyService/ToUpper\')]</add>
</filters>
</messageLogging>
</diagnostics>
</system.serviceModel>
<system.diagnostics>
<sources>
<source name=\"System.ServiceModel.MessageLogging\">
<listeners>
<add name=\"ServiceModelTraceListener\" />
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData=\"LogServer.svclog\" type=\"System.Diagnostics.XmlWriterTraceListener\" name=\"ServiceModelTraceListener\" />
</sharedListeners>
<trace autoflush=\"true\" />
</system.diagnostics>
如果我应用此过滤器,则日志中不会有任何消息...
那么,关于上面的链接示例,我在做什么错呢?
如果没有过滤器,则默认消息(使用字符串参数“ 6”调用的方法“ 2”)的xml跟踪如下所示:
<E2ETraceEvent xmlns=\"http://schemas.microsoft.com/2004/06/E2ETraceEvent\">
<System xmlns=\"http://schemas.microsoft.com/2004/06/windows/eventlog/system\">
<EventID>0</EventID>
<Type>3</Type>
<SubType Name=\"Information\">0</SubType>
<Level>8</Level>
<TimeCreated SystemTime=\"2011-05-27T17:53:53.9908714Z\" />
<Source Name=\"System.ServiceModel.MessageLogging\" />
<Correlation ActivityID=\"{00000000-0000-0000-0000-000000000000}\" />
<Execution ProcessName=\"WcfLoggingTest.Host.vshost\" ProcessID=\"4324\" ThreadID=\"12\" />
<Channel />
<Computer>MY-Machine</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<MessageLogTraceRecord Time=\"2011-05-27T19:53:53.9908714+02:00\" Source=\"TransportReceive\" Type=\"System.ServiceModel.Channels.BufferedMessage\" xmlns=\"http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace\">
<HttpRequest>
<Method>POST</Method>
<QueryString></QueryString>
<WebHeaders>
<VsDebuggerCausalityData>uIDPozEtlPQCjkhCodYdPWh6joUAAAAAamILDP7v3kG5sY6zKsB7HPPiLBWr+AVGmfFDQbk8GYAACQAA</VsDebuggerCausalityData>
<SOAPAction>\"http://myNamespace.org/IMyService/ToUpper\"</SOAPAction>
<Content-Length>157</Content-Length>
<Content-Type>text/xml; charset=utf-8</Content-Type>
<Accept-Encoding>gzip,deflate</Accept-Encoding>
<Expect>100-continue</Expect>
<Host>localhost:8731</Host>
</WebHeaders>
</HttpRequest>
<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">
<s:Header>
<To s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">http://localhost:8731/Design_Time_Addresses/MyService/</To>
<Action s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">http://myNamespace.org/IMyService/ToUpper</Action>
</s:Header>
<s:Body>
<ToUpper xmlns=\"http://myNamespace.org/\">
<s>hello</s>
</ToUpper>
</s:Body>
</s:Envelope>
</MessageLogTraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>
更新:
对于每个对解决方案感兴趣的机构,我终于在jasso的帮助下与它合作,谢谢:
<add xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:a=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">/soap:Envelope/soap:Header/a:Action[starts-with(text(),\'http://myNamespace.org/IMyService/ToUpper\')]</add>
然后,我编辑了我的界面,并添加了方法“ 9”到“ 10”。然后我的目标是记录所有与Method1
和Method3
相关的消息之外的所有消息。我使用以下过滤器进行了此操作:
<add xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:a=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">/soap:Envelope/soap:Header/a:Action[starts-with(text(),\'http://myNamespace.org/IMyService/Method1\')=false() and starts-with(text(),\'http://myNamespace.org/IMyService/Method3\')=false()]</add>
这样,仅记录与Invert
,ToUpper
和Method2
相关的消息。
使用两个单独的过滤器来处理此问题可能是一种更干净的方法,但是目前我对此非常满意。
解决方法
您在XPath表达式中的
Action
元素使用了错误的命名空间
你有
xmlns:a=\"http://www.w3.org/2005/08/addressing\"
... /a:Action[starts-with ...
并且文件有
<Action s:mustUnderstand=\"1\" xmlns=\"http://schemas.microsoft.com/ws/2005/05/addressing/none\">
因此名称空间有所不同,因为Action
元素具有附加的默认名称空间定义。
另外,您的XPath也在搜索soap:Envelope
根元素,因为您的表达式以/
开头。我对框架不熟悉,它可能会从示例XML(肥皂内容)中选择一个子树,然后应用XPath过滤器。如果不是这种情况,并且您的XPath应该在给定的XML文档上产生匹配项,那么您应该以//
或以soap:Envelope
元素的路径(例如/*/*/*/*/*/soap:Envelope
)开始表达式。首先使用//
运算符效率低下,因为它需要遍历整个文档中的所有节点。
, 非常感谢您提供有用的信息!
根据我自己的研究,要成功执行过滤,还必须强制执行以下关键点:
请勿以双\“ / \”开头的XPath表达式,否则过滤将根本无法进行。尽管对于XPath语法,此双\ /是正确的(与jasso指出的2011年5月27日23:06相同)。
不要依赖WCF配置编辑工具来为所涉及的xml名称空间选择别名。到现在为止发现\“ s12 \”不起作用,但是\“ s \”或\“ s1a \”是可以的(也许这是Microsoft所做的错误,我不确定)。
, XPath查询可能是问题所在。试试这个简单的版本:
<filters>
<add xmlns:msgtr=\"http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace\" >//msgtr:SOAPAction[contains(.,\'ToUpper\')]</add>
</filters>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。