How do I get the XML SOAP request of an WCF Web service request?

后端 未结 7 636
太阳男子
太阳男子 2020-12-07 08:28

I\'m calling this web service within code and I would like to see the XML, but I can\'t find a property that exposes it.

相关标签:
7条回答
  • 2020-12-07 09:09

    There is an another way to see XML SOAP - custom MessageEncoder. The main difference from IClientMessageInspector is that it works on lower level, so it captures original byte content including any malformed xml.

    In order to implement tracing using this approach you need to wrap a standard textMessageEncoding with custom message encoder as new binding element and apply that custom binding to endpoint in your config.

    Also you can see as example how I did it in my project - wrapping textMessageEncoding, logging encoder, custom binding element and config.

    0 讨论(0)
  • 2020-12-07 09:10

    I just wanted to add this to the answer from Kimberly. Maybe it can save some time and avoid compilation errors for not implementing all methods that the IEndpointBehaviour interface requires.

    Best regards

    Nicki

        /*
            // This is just to illustrate how it can be implemented on an imperative declarared binding, channel and client.
    
            string url = "SOME WCF URL";
            BasicHttpBinding wsBinding = new BasicHttpBinding();                
            EndpointAddress endpointAddress = new EndpointAddress(url);
    
            ChannelFactory<ISomeService> channelFactory = new ChannelFactory<ISomeService>(wsBinding, endpointAddress);
            channelFactory.Endpoint.Behaviors.Add(new InspectorBehavior());
            ISomeService client = channelFactory.CreateChannel();
        */    
            public class InspectorBehavior : IEndpointBehavior
            {
                public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
                {
                    // No implementation necessary  
                }
    
                public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
                {
                    clientRuntime.MessageInspectors.Add(new MyMessageInspector());
                }
    
                public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
                {
                    // No implementation necessary  
                }
    
                public void Validate(ServiceEndpoint endpoint)
                {
                    // No implementation necessary  
                }  
    
            }
    
            public class MyMessageInspector : IClientMessageInspector
            {
                public object BeforeSendRequest(ref Message request, IClientChannel channel)
                {
                    // Do something with the SOAP request
                    string request = request.ToString();
                    return null;
                }
    
                public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
                {
                    // Do something with the SOAP reply
                    string replySoap = reply.ToString();
                }
            }
    
    0 讨论(0)
  • 2020-12-07 09:10

    I am using below solution for IIS hosting in ASP.NET compatibility mode. Credits to Rodney Viana's MSDN blog.

    Add following to your web.config under appSettings:

    <add key="LogPath" value="C:\\logpath" />
    <add key="LogRequestResponse" value="true" />
    

    Replace your global.asax.cs with below (also fix namespace name):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.SessionState;
    
    using System.Text;
    using System.IO;
    using System.Configuration;
    
    namespace Yournamespace
    {
        public class Global : System.Web.HttpApplication
        {
            protected static bool LogFlag;
            protected static string fileNameBase;
            protected static string ext = "log";
    
            // One file name per day
            protected string FileName
            {
                get
                {
                    return String.Format("{0}{1}.{2}", fileNameBase, DateTime.Now.ToString("yyyy-MM-dd"), ext);
                }
            }
    
            protected void Application_Start(object sender, EventArgs e)
            {
                LogFlag = bool.Parse(ConfigurationManager.AppSettings["LogRequestResponse"].ToString());
                fileNameBase = ConfigurationManager.AppSettings["LogPath"].ToString() + @"\C5API-";   
            }
    
            protected void Session_Start(object sender, EventArgs e)
            {
    
            }
    
            protected void Application_BeginRequest(object sender, EventArgs e)
            {
                if (LogFlag) 
                {                
                    // Creates a unique id to match Rquests with Responses
                    string id = String.Format("Id: {0} Uri: {1}", Guid.NewGuid(), Request.Url);
                    FilterSaveLog input = new FilterSaveLog(HttpContext.Current, Request.Filter, FileName, id);
                    Request.Filter = input;
                    input.SetFilter(false);
                    FilterSaveLog output = new FilterSaveLog(HttpContext.Current, Response.Filter, FileName, id);
                    output.SetFilter(true);
                    Response.Filter = output;
                }
            }
    
            protected void Application_AuthenticateRequest(object sender, EventArgs e)
            {
    
            }
    
            protected void Application_Error(object sender, EventArgs e)
            {
    
            }
    
            protected void Session_End(object sender, EventArgs e)
            {
    
            }
    
            protected void Application_End(object sender, EventArgs e)
            {
    
            }
        }
    
        class FilterSaveLog : Stream
        {
    
            protected static string fileNameGlobal = null;
            protected string fileName = null;
    
            protected static object writeLock = null;
            protected Stream sinkStream;
            protected bool inDisk;
            protected bool isClosed;
            protected string id;
            protected bool isResponse;
            protected HttpContext context;
    
            public FilterSaveLog(HttpContext Context, Stream Sink, string FileName, string Id)
            {
                // One lock per file name
                if (String.IsNullOrWhiteSpace(fileNameGlobal) || fileNameGlobal.ToUpper() != fileNameGlobal.ToUpper())
                {
                    fileNameGlobal = FileName;
                    writeLock = new object();
                }
                context = Context;
                fileName = FileName;
                id = Id;
                sinkStream = Sink;
                inDisk = false;
                isClosed = false;
            }
    
            public void SetFilter(bool IsResponse)
            {
    
    
                isResponse = IsResponse;
                id = (isResponse ? "Reponse " : "Request ") + id;
    
                //
                // For Request only read the incoming stream and log it as it will not be "filtered" for a WCF request
                //
                if (!IsResponse)
                {
                    AppendToFile(String.Format("at {0} --------------------------------------------", DateTime.Now));
                    AppendToFile(id);
    
                    if (context.Request.InputStream.Length > 0)
                    {
                        context.Request.InputStream.Position = 0;
                        byte[] rawBytes = new byte[context.Request.InputStream.Length];
                        context.Request.InputStream.Read(rawBytes, 0, rawBytes.Length);
                        context.Request.InputStream.Position = 0;
    
                        AppendToFile(rawBytes);
                    }
                    else
                    {
                        AppendToFile("(no body)");
                    }
                }
    
            }
    
            public void AppendToFile(string Text)
            {
                byte[] strArray = Encoding.UTF8.GetBytes(Text);
                AppendToFile(strArray);
    
            }
    
            public void AppendToFile(byte[] RawBytes)
            {
                bool myLock = System.Threading.Monitor.TryEnter(writeLock, 100);
    
    
                if (myLock)
                {
                    try
                    {
    
                        using (FileStream stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                        {
                            stream.Position = stream.Length;
                            stream.Write(RawBytes, 0, RawBytes.Length);
                            stream.WriteByte(13);
                            stream.WriteByte(10);
    
                        }
    
                    }
                    catch (Exception ex)
                    {
                        string str = string.Format("Unable to create log. Type: {0} Message: {1}\nStack:{2}", ex, ex.Message, ex.StackTrace);
                        System.Diagnostics.Debug.WriteLine(str);
                        System.Diagnostics.Debug.Flush();
    
    
                    }
                    finally
                    {
                        System.Threading.Monitor.Exit(writeLock);
    
    
                    }
                }
    
    
            }
    
    
            public override bool CanRead
            {
                get { return sinkStream.CanRead; }
            }
    
            public override bool CanSeek
            {
                get { return sinkStream.CanSeek; }
            }
    
            public override bool CanWrite
            {
                get { return sinkStream.CanWrite; }
            }
    
            public override long Length
            {
                get
                {
                    return sinkStream.Length;
                }
            }
    
            public override long Position
            {
                get { return sinkStream.Position; }
                set { sinkStream.Position = value; }
            }
    
            //
            // For WCF this code will never be reached
            //
            public override int Read(byte[] buffer, int offset, int count)
            {
                int c = sinkStream.Read(buffer, offset, count);
                return c;
            }
    
            public override long Seek(long offset, System.IO.SeekOrigin direction)
            {
                return sinkStream.Seek(offset, direction);
            }
    
            public override void SetLength(long length)
            {
                sinkStream.SetLength(length);
            }
    
            public override void Close()
            {
    
                sinkStream.Close();
                isClosed = true;
            }
    
            public override void Flush()
            {
    
                sinkStream.Flush();
            }
    
            // For streamed responses (i.e. not buffered) there will be more than one Response (but the id will match the Request)
            public override void Write(byte[] buffer, int offset, int count)
            {
                sinkStream.Write(buffer, offset, count);
                AppendToFile(String.Format("at {0} --------------------------------------------", DateTime.Now));
                AppendToFile(id);
                AppendToFile(buffer);
            }
    
        }
    }
    

    It should create log file in the folder LogPath with request and response XML.

    0 讨论(0)
  • 2020-12-07 09:12

    Option 1

    Use message tracing/logging.

    Have a look here and here.


    Option 2

    You can always use Fiddler to see the HTTP requests and response.


    Option 3

    Use System.Net tracing.

    0 讨论(0)
  • 2020-12-07 09:13

    Simply we can trace the request message as.

    OperationContext context = OperationContext.Current;
    
    if (context != null && context.RequestContext != null)
    
    {
    
    Message msg = context.RequestContext.RequestMessage;
    
    string reqXML = msg.ToString();
    
    }
    
    0 讨论(0)
  • 2020-12-07 09:27
    OperationContext.Current.RequestContext.RequestMessage 
    

    this context is accesible server side during processing of request. This doesn`t works for one-way operations

    0 讨论(0)
提交回复
热议问题