我在Windows上使用asp.net核心,并且有一个由dotnet-svcutil生成的类的文件。我正在使用nlog进行日志记录。有没有办法可以记录外部服务的所有原始请求和响应?
已经尝试过logman https://github.com/dotnet/wcf/blob/master/Documentation/HowToUseETW.md,但首先 - 它不显示原始肥皂,只显示事件,第二 - 我需要通过配置的nlog记录日志。
行为:
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;
}
}
用法:
if (configuration.GetValue<bool>("Logging:MessageContent"))
client.Endpoint.EndpointBehaviors.Add(serviceProvider.GetRequiredService<LoggingEndpointBehaviour>());
在这里找到答案:https://msdn.microsoft.com/en-us/library/ms733786.aspx
行动顺序:
- 实现System.ServiceModel.Dispatcher.IClientMessageInspector接口。在这里,您可以检查/修改/记录消息
- 根据要插入客户端消息检查器的范围,实现System.ServiceModel.Description.IEndpointBehavior或System.ServiceModel.Description.IContractBehavior。 System.ServiceModel.Description.IEndpointBehavior允许您更改端点级别的行为。 System.ServiceModel.Description.IContractBehavior允许您更改合同级别的行为。
- 在System.ServiceModel.ChannelFactory上调用ClientBase.Open或ICommunicationObject.Open方法之前插入行为。