WCF:如何手动记录原始xml消息内容?

问题描述 投票:0回答:1

我有一个简单的经典ASP网站,该网站使用WCF调用SOAP API。为了进行调试,我需要将XML消息内容手动记录到单独的日志文件中。

例如,12/23 / 18_34.txt文件包含在12/23的18:34发送的XML请求。我通读了许多记录WCF XML消息的文章,并找到了这两种方法。

  1. 使用消息记录功能。
  2. 使用IClientMessageInspector。

我可以使用第一种方法进行记录,但是这样做无法将消息内容保存到具有特定名称的单独文件中。所以我尝试了第二种方法,但是它不起作用,而且我找不到错误所在。

由于当前项目是一个经典的ASP网站,并且没有名称空间,所以我不确定如何在web.config文件中设置type属性的值。我设法通过创建一个单独的具有BehaviorExtensionElement的dll文件来添加它,并将其复制到当前项目的Bin文件夹中。

<add name="logXmlBehavior" type="MessageLogger.MessageLoggerBehaviorExtensionElement, MessageLogger, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
public class MessageLogger : IClientMessageInspector
    {
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            MessageBuffer buffer = reply.CreateBufferedCopy(Int32.MaxValue);
            reply = buffer.CreateMessage();

            var fileName = DateTime.Now.ToString("dd_HHmm");
            System.IO.File.WriteAllText($"C:/Logs/Symmetry/{fileName}_response.txt", buffer.CreateMessage().ToString());
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            MessageBuffer buffer = request.CreateBufferedCopy(Int32.MaxValue);
            request = buffer.CreateMessage();

            var fileName = DateTime.Now.ToString("dd_HHmm");
            System.IO.File.WriteAllText($"C:/Logs/Symmetry/{fileName}_post.txt", buffer.CreateMessage().ToString());
            return null;
        }
    }

这是我的MessageLogger类,但不记录任何内容。 🤕

如何在没有单独的DLL的情况下将BehaviorExtensionElement添加到经典ASP网站?为什么我当前的记录器不起作用?

PS:该网站使用IIS托管。

c# asp.net wcf iis asp-classic
1个回答
0
投票

您的代码段似乎没有问题。请参考我的例子。MessageLogger类。

    public class ClientMessageLogger : IClientMessageInspector
    {
        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            string displayText = $"the client has received the reply:\n{reply}\n";
            Console.Write(displayText);
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            string displayText = $"the client send request message:\n{request}\n";
            Console.WriteLine(displayText);
            return null;
        }
}

要在客户端服务端点上应用的端点行为。

public class AuthBehavior : BehaviorExtensionElement, IEndpointBehavior
    {
        public override Type BehaviorType => typeof(AuthBehavior);
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }
        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            ClientMessageLogger inspector = new ClientMessageLogger();
            clientRuntime.ClientMessageInspectors.Add(inspector);
        }
        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
        }
        public void Validate(ServiceEndpoint endpoint)
        {
        }
        protected override object CreateBehavior()
        {
            return new AuthBehavior();
        }
    }

然后,我在扩展部分中注册端点行为,并将其应用于自动生成的客户端服务端点。

    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IService" />
            </basicHttpBinding>
        </bindings>
        <client>
          <!--apply it on the endpoint-->
            <endpoint address="http://localhost:1300/" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
                name="BasicHttpBinding_IService" behaviorConfiguration="authBehavior" />
        </client>
      <behaviors>
        <endpointBehaviors>
          <behavior name="authBehavior">
            <authbehavior />
          </behavior>
        </endpointBehaviors>
      </behaviors>
      <extensions>
        <behaviorExtensions>
          <!--like yours, namespace.class,assembly-->
          <add name="authbehavior" type="Client3.AuthBehavior,Client3,Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
        </behaviorExtensions>
      </extensions>
</system.serviceModel>

最终,当向服务器发送请求时,控制台应用程序正确记录了消息。

ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
        //client.Endpoint.EndpointBehaviors.Add(new AuthBehavior());
        try
        {
            Console.WriteLine(client.SayHello());
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

结果。enter image description here此外,我认为WCF跟踪也可以完成记录通信消息的任务。只需添加以下配置,检查bin文件夹中的mylogs.svclog文件。

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
          <add type="System.Diagnostics.XmlWriterTraceListener" name="xmlLog" initializeData="myLogs.svclog"/>
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_IService" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://10.157.13.70:1300/" binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IService" contract="ServiceReference1.IService"
        name="BasicHttpBinding_IService" />
    </client>
    <diagnostics>
      <messageLogging logEntireMessage="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="false"/>
    </diagnostics>
  </system.serviceModel>

随时让我知道是否有什么我可以帮助的。

© www.soinside.com 2019 - 2024. All rights reserved.