C# WCF客户端日志记录dotnet核心
我正在windows上使用asp.net核心,并且有一个包含由dotnet svcuti生成的类的文件。我使用nlog进行日志记录。是否有一种方法可以记录与外部服务之间的所有原始请求和响应 已经尝试过logman,但首先-它不显示原始soap,只显示事件,其次-我需要配置的nlog记录日志。在这里找到了答案: 行动顺序:C# WCF客户端日志记录dotnet核心,c#,wcf,soap,asp.net-core,svcutil.exe,C#,Wcf,Soap,Asp.net Core,Svcutil.exe,我正在windows上使用asp.net核心,并且有一个包含由dotnet svcuti生成的类的文件。我使用nlog进行日志记录。是否有一种方法可以记录与外部服务之间的所有原始请求和响应 已经尝试过logman,但首先-它不显示原始soap,只显示事件,其次-我需要配置的nlog记录日志。在这里找到了答案: 行动顺序: 实现System.ServiceModel.Dispatcher.IClientMessageInspector接口您可以在此处检查/修改/记录消息 根据要插入客户端消息检查
public class LoggingEndpointBehaviour : IEndpointBehavior
{
public LoggingMessageInspector MessageInspector { get; }
public LoggingEndpointBehaviour(LoggingMessageInspector messageInspector)
{
MessageInspector = messageInspector ?? throw new ArgumentNullException(nameof(messageInspector));
}
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(MessageInspector);
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
检查员:
public class LoggingMessageInspector : IClientMessageInspector
{
public LoggingMessageInspector(ILogger<LoggingMessageInspector> logger)
{
Logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
}
public ILogger<LoggingMessageInspector> Logger { get; }
public void AfterReceiveReply(ref Message reply, object correlationState)
{
using (var buffer = reply.CreateBufferedCopy(int.MaxValue))
{
var document = GetDocument(buffer.CreateMessage());
Logger.LogTrace(document.OuterXml);
reply = buffer.CreateMessage();
}
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
using (var buffer = request.CreateBufferedCopy(int.MaxValue))
{
var document = GetDocument(buffer.CreateMessage());
Logger.LogTrace(document.OuterXml);
request = buffer.CreateMessage();
return null;
}
}
private XmlDocument GetDocument(Message request)
{
XmlDocument document = new XmlDocument();
using (MemoryStream memoryStream = new MemoryStream())
{
// write request to memory stream
XmlWriter writer = XmlWriter.Create(memoryStream);
request.WriteMessage(writer);
writer.Flush();
memoryStream.Position = 0;
// load memory stream into a document
document.Load(memoryStream);
}
return document;
}
}
公共类LoggingMessageInspector:IClientMessageInspector
{
公共日志消息检查器(ILogger记录器)
{
Logger=Logger??抛出新系统.ArgumentNullException(name of(Logger));
}
公共ILogger记录器{get;}
接收后公共无效(参考消息回复,对象关联状态)
{
使用(var buffer=reply.CreateBufferedCopy(int.MaxValue))
{
var document=GetDocument(buffer.CreateMessage());
LogTrace(document.OuterXml);
reply=buffer.CreateMessage();
}
}
发送请求前的公共对象(参考消息请求,IClientChannel通道)
{
使用(var buffer=request.CreateBufferedCopy(int.MaxValue))
{
var document=GetDocument(buffer.CreateMessage());
LogTrace(document.OuterXml);
request=buffer.CreateMessage();
返回null;
}
}
私有XmlDocument GetDocument(消息请求)
{
XmlDocument document=新的XmlDocument();
使用(MemoryStream MemoryStream=new MemoryStream())
{
//将请求写入内存流
XmlWriter=XmlWriter.Create(memoryStream);
请求.书面信息(编写者);
writer.Flush();
memoryStream.Position=0;
//将内存流加载到文档中
文件加载(memoryStream);
}
归还文件;
}
}
用法:
if (configuration.GetValue<bool>("Logging:MessageContent"))
client.Endpoint.EndpointBehaviors.Add(serviceProvider.GetRequiredService<LoggingEndpointBehaviour>());
if(configuration.GetValue(“Logging:MessageContent”))
client.Endpoint.EndpointBehaviors.Add(serviceProvider.GetRequiredService());
这个答案的用法部分对我很有帮助。我要指出的是,您还可以将该类添加到EndpointBehavior中,如下所示:client.Endpoint.endpointBehavior.add(new LoggingEndpointBehavior()),前提是您要实现的类具有无参数构造函数。我在过去三个小时中一直在尝试捕获我的请求和响应。做了所有建议的事。尤其是消息检查器。但是,除了你的解释外,由于解释不当,它们都不起作用。你真的救了我一天。