How to get WCF web service request XML SOAP request?

I call this web service in code and I would like to see XML, but I cannot find a property that exposes it.

+55
c # soap xml wcf
Mar 30 '11 at 23:20
source share
5 answers

I think you meant that you want to see XML on the client, and not trace it on the server. In this case, your answer is in the question that I linked above, as well as in How to check or modify messages on the client . But since C # is missing from the .NET version of this article, and there is some confusion (if not an error) in the .NET 3.5 example, here it is extended for your purpose.

You can intercept the message before it disappears using IClientMessageInspector :

using System.ServiceModel.Dispatcher; public class MyMessageInspector : IClientMessageInspector { } 

The methods in this BeforeSendRequest and AfterReceiveReply give you access to the request and response. To use the inspector, you need to add it to IEndpointBehavior :

 using System.ServiceModel.Description; public class InspectorBehavior : IEndpointBehavior { public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { clientRuntime.MessageInspectors.Add(new MyMessageInspector()); } } 

You can leave other methods of this interface empty implementations if you do not want to use their functionality. Read more in the instructions.

After creating the client instance, add behavior to the endpoint. Using the default names from the WCF sample project:

 ServiceReference1.Service1Client client = new ServiceReference1.Service1Client(); client.Endpoint.Behaviors.Add(new InspectorBehavior()); client.GetData(123); 

Set a breakpoint in MyMessageInspector.BeforeSendRequest() ; request.ToString() overloaded to show XML.

If you intend to manipulate messages at all, you should work on a copy of the message. See Using the message class for more information .

Thanks to Zach Bonham 's answer on another question for finding these links.

+102
Mar 31 '11 at
source share

Option 1

Use message tracking / logging .

Look here and here .




Option 2

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




Option 3

Use System.Net Tracking .

+26
Mar 30 '11 at 23:27
source share
 OperationContext.Current.RequestContext.RequestMessage 

this context is available to the server side during request processing. This does not work for one-way operations.

+6
Feb 27 '14 at 6:51
source share

We can simply trace the request message as.

 OperationContext context = OperationContext.Current; if (context != null && context.RequestContext != null) { Message msg = context.RequestContext.RequestMessage; string reqXML = msg.ToString(); } 
+6
Feb 18 '15 at 7:01
source share

I am using the below solution for the IIS host in ASP.NET compatibility mode. Credits for Rodney Viana MSDN Blog .

Add the following to your web.config in the appSettings section:

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

Replace the global.asax.cs file below (also correct the 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 (ie 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); } } } 

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

0
May 11 '15 at 6:20
source share



All Articles