如何添加要通过 WCF 中的策略注入记录的自定义上下文数据?
我们都知道将 WCF 与 PIAB 结合起来解决横切问题(例如日志记录、验证、审核等)是完全可以的(请访问 http://msdn.microsoft.com/en-us/magazine/cc136759.aspx)。
但 bog 标准日志调用处理程序仅支持日志的一组有限的“扩展属性”。如果需要记录其他信息(例如:客户端 IP 地址、用户 ID 等)怎么办?
答案(由于 stackoverflow 对低评分会员的奇怪政策,稍后将添加为答案):
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
经过多次挖掘后,我想出了这个解决方案,我希望它能让其他有相同查询的人受益。
首先,您需要有一个自定义调用处理程序来包含您想要的日志的所有附加数据。您可以参考entlib源代码并查找LogCallHandler。在 GetLogEntry 私有方法中添加附加数据:
之后,您必须创建基础设施以将上下文数据从客户端传播到服务器。我有一个 CallContext 的包装类来存储上下文数据的字典对象:
在服务客户端上,此上下文将通过实现 IClientMessageInspector 添加到请求消息标头。
在服务方面,我有一个 ICallContextInitializer 的自定义实现,用于从传入消息中检索消息标头并将其设置回传出消息:
这本质上是消息标头有效负载的往返行程。在 AfterInvoke 方法中,可以在发送回之前修改消息标头。
最后,我创建了一个端点行为来应用 MessageInspector 和 CallContextInitializer。
您还可以编写合同行为,通过使用行为属性装饰您的服务/合同来实现相同的目的。
现在,您可以从服务客户端设置所有上下文数据,如下所示:
这也发布在 entlib.codeplex 的讨论板上:http://entlib.codeplex.com/discussions/266963
After much digging around I came up with this solution which I hope will benefit others with the same query.
First of all, you need to have a custom call handler to include all the additional data you want for your logs. You can refer to the entlib source code and look for LogCallHandler. Add the additional data in GetLogEntry private method:
After thatn, you have to creat the infrastruture to propagate context data from client to server. I have a wrapper class for CallContext to store a dictionary object for context data:
On the service client, this context will be added to the request message header through implementing IClientMessageInspector.
On the service side, I have a custom implementation of ICallContextInitializer to retrieve the message header from the incoming message and set it back to the outgoing message:
This essentially is a round trip for the message header payload to travel. In the AfterInvoke method, the message header could be modified before being sent back.
Finally, I have created an endpoint behaviour to apply the MessageInspector and CallContextInitializer.
You could also write a contract behaviour to achieve the same by decorating your service/contract with the behaviour attribute.
Now from your service client, you can set all the context data like below:
This is also posted on the discussion board of entlib.codeplex at: http://entlib.codeplex.com/discussions/266963