C# ASP.NET内核中的WCF跟踪

C# ASP.NET内核中的WCF跟踪,c#,asp.net,.net,wcf,asp.net-core,C#,Asp.net,.net,Wcf,Asp.net Core,我们过去在ASP.NET上使用WCF,最近在ASP.NET核心上切换到WCF。这很难实现,因为ASP.NETCore不支持现成的WCF。首先,整个web.config XML配置模型已转储到ASP.NET核心中,因此我们无法在那里配置WCF跟踪 即本文件无效: 我们必须通过在WCF和端口80之间放置http代理来攻击ASP.NET核心。WCF实际上正在另一个端口上运行 问题是,如果ASP.NET Core不注意web.config,我们如何启用WCF跟踪?您将在.NET Core上对WCF使用

我们过去在ASP.NET上使用WCF,最近在ASP.NET核心上切换到WCF。这很难实现,因为ASP.NETCore不支持现成的WCF。首先,整个web.config XML配置模型已转储到ASP.NET核心中,因此我们无法在那里配置WCF跟踪

即本文件无效:

我们必须通过在WCF和端口80之间放置http代理来攻击ASP.NET核心。WCF实际上正在另一个端口上运行


问题是,如果ASP.NET Core不注意web.config,我们如何启用WCF跟踪?

您将在.NET Core上对WCF使用ETW跟踪

根据我的经验,你有一些局限性

  • 所有WCF应用程序的跟踪都处于启用状态,而不是通过配置文件为单个应用程序进行配置
  • 不能使用ETW跟踪输出消息
  • SvcTraceViewer.exe不能很好地用于跟踪审阅,您需要转到PerfView.exe,这可能会呈现学习曲线
  • ETW的好处

  • 您可以避免经典形式的跟踪对性能的影响
  • 不再更改启动/停止跟踪的配置

  • 在客户端跟踪的情况下,我使用自定义端点行为(
    IEndpointBehavior
    )和自定义消息日志检查器(
    IClientMessageInspector
    )来获取输入和输出消息

    客户端初始化:

    _serviceClient = new MyCustomServiceClient();
    _serviceClient.Endpoint.Address = new System.ServiceModel.EndpointAddress(_configParams.ServiceUri);
    _serviceClient.Endpoint.EndpointBehaviors.Add(new EndpointLoggingBehavior("MyCustomService"));
    
    EndpointLoggingBehavior
    的实现:

    public class EndpointLoggingBehavior : IEndpointBehavior
        {
            public EndpointLoggingBehavior(string serviceName)
            {
                _serviceName = serviceName;
            }
    
            private readonly string _serviceName;
    
            public void AddBindingParameters(ServiceEndpoint endpoint,
                System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
            {
            }
    
            public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
            {
                clientRuntime.ClientMessageInspectors.Add(new MessageLoggingInspector(_serviceName));
            }
    
            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
            {
            }
    
            public void Validate(ServiceEndpoint endpoint)
            {
            }
        }
    
    public class MessageLoggingInspector : IClientMessageInspector
        {
            private readonly string _serviceName;
            public MessageLoggingInspector(string serviceName)
            {
                _serviceName = serviceName;
            }
            public void AfterReceiveReply(ref Message reply, object correlationState)
            {
                // copying message to buffer to avoid accidental corruption
                var buffer = reply.CreateBufferedCopy(int.MaxValue);
                reply = buffer.CreateMessage();
                // creating copy
                var copy = buffer.CreateMessage();
                //getting full input message
                var fullInputMessage = copy.ToString();
    
            }
            public object BeforeSendRequest(ref Message request, IClientChannel channel)
            {
                // copying message to buffer to avoid accidental corruption
                var buffer = request.CreateBufferedCopy(int.MaxValue);
                request = buffer.CreateMessage();
                // creating copy
                var copy = buffer.CreateMessage();
                //getting full output message
                var fullOutputMessage = copy.ToString();
                return null;
            }
        }
    
    MessageLoggingInspector的实现

    public class EndpointLoggingBehavior : IEndpointBehavior
        {
            public EndpointLoggingBehavior(string serviceName)
            {
                _serviceName = serviceName;
            }
    
            private readonly string _serviceName;
    
            public void AddBindingParameters(ServiceEndpoint endpoint,
                System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
            {
            }
    
            public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
            {
                clientRuntime.ClientMessageInspectors.Add(new MessageLoggingInspector(_serviceName));
            }
    
            public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
            {
            }
    
            public void Validate(ServiceEndpoint endpoint)
            {
            }
        }
    
    public class MessageLoggingInspector : IClientMessageInspector
        {
            private readonly string _serviceName;
            public MessageLoggingInspector(string serviceName)
            {
                _serviceName = serviceName;
            }
            public void AfterReceiveReply(ref Message reply, object correlationState)
            {
                // copying message to buffer to avoid accidental corruption
                var buffer = reply.CreateBufferedCopy(int.MaxValue);
                reply = buffer.CreateMessage();
                // creating copy
                var copy = buffer.CreateMessage();
                //getting full input message
                var fullInputMessage = copy.ToString();
    
            }
            public object BeforeSendRequest(ref Message request, IClientChannel channel)
            {
                // copying message to buffer to avoid accidental corruption
                var buffer = request.CreateBufferedCopy(int.MaxValue);
                request = buffer.CreateMessage();
                // creating copy
                var copy = buffer.CreateMessage();
                //getting full output message
                var fullOutputMessage = copy.ToString();
                return null;
            }
        }
    

    当然,您需要将这些消息写入任何存储。

    WCF可以像RestFul服务一样使用webhttp绑定。所以它可以用来代替webApi项目WCF太复杂了,这就是为什么需要跟踪。为什么需要在ASP.NET核心中进行跟踪?请将两者分开,不要用别人都不采用的方法来麻烦自己。你认为我想支持一种过时的技术吗?如果有办法摆脱它,我会的。不要用无益的评论来打扰自己。彼得,谢谢你的建议,我从。一个建议是:在代码中的“copy.ToString();”之后添加类似“Then,当然了…”的注释,例如“//将消息写入存储器或记录器”。WCF非常难学——从我的观点来看,它太难了,它是金锤反模式的一个机会——所以代码中的任何提示都可以节省时间。在我的例子中,我在MessageLoggingInspector的构造函数中注入了一个记录器。