Click to See Complete Forum and Search --> : How to get the XML out of a SOAP request Pls. help
Lars_V_J
August 18th, 2009, 02:52 AM
I have made some SOAP code by using svcutil.exe on the wsdl file, and I wish to somehow dump/get the XML that the request contains. How do I do that?
Thank you in advance.
Edit: Oh I forgot: I use .Net 2008
dannystommen
August 18th, 2009, 03:49 AM
This is from the support of a 3the party webservice I'm using
•Save the following code (http://msdn.microsoft.com/en-us/library/ms179346.aspx) with the name "SqlSoapTracer.cs" in the same folder that contains the SOAP client project files.
•In the Solution Explorer window, perform the following steps:
◦Select the project by name, right-click and point to Add, and then select Add Existing Item.
◦In the Add Existing Item dialog box, browse and select the SqlSoapTracer.cs file from the location you saved it to in step 1.
◦Select Show All Files and expand the Web References node and select the Reference.cs file.
•In the Code Editor window, update the Reference.cs file by locating the entry points for your Web methods there. To add SOAP trace support when the Web methods execute in client code, add the following snoopattribute() call in the Reference.cs code directly before the entry point for each Web method you want to trace, as shown in the following lines of code.
[System.Web.Services.Protocols.SoapRpcMethodAttribute("urn:ContactService#login",
RequestNamespace="urn:ContactService", ResponseNamespace="urn:ContactService")]
[return: System.Xml.Serialization.SoapElementAttribute("token")]
[snoopattribute()]
public string login(string user, string pass, login_options login_options) {
object[] results = this.Invoke("login", new object[] {
user,
pass,
login_options});
return ((string)(results[0]));
}
This registers a SOAP extension that invokes the SOAP tracing of these Web methods when they are executed.
In the method 'ProcessMessage(SoapMessage message)', the request is save into the Clipboard.
To make it more easy to read, you can add your own method to the class that writes the request to a file instead of the clipboard.
The new 'ProcessMessage(SoapMessage message)' looks then like the next
public override void ProcessMessage(SoapMessage message) {
SoapClientMessage client = (SoapClientMessage)message;
switch (client.Stage) {
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
try {
m_newStream.Position = 0;
StreamReader reader = new StreamReader(m_newStream);
m_info.request = FormatXml(reader.ReadToEnd());
m_newStream.Position = 0;
m_newStream.SetLength(0);
StreamWriter writer = new StreamWriter(m_newStream);
writer.Write(m_info.request);
writer.Flush();
Clipboard.SetDataObject(m_info.request + "\r\n", true);
SaveStream(m_info.request + "\r\n");
}
catch (Exception e) {
m_info.requestException = e;
}
m_newStream.Position = 0;
Copy(m_newStream, m_oldStream);
break;
case SoapMessageStage.BeforeDeserialize:
m_newStream.SetLength(0);
try {
Copy(m_oldStream, m_newStream);
m_newStream.Position = 0;
StreamReader reader = new StreamReader(m_newStream);
string tempData = reader.ReadToEnd();
m_info.response = FormatXml(tempData);
m_newStream.Position = 0;
m_newStream.SetLength(0);
StreamWriter writer = new StreamWriter(m_newStream);
writer.Write(tempData);
writer.Flush();
Clipboard.SetDataObject(m_info.request + "\r\n\r\n" + m_info.response + "\r\n", true);
SaveStream(m_info.request + "\r\n\r\n" + m_info.response + "\r\n");
}
catch (Exception e) {
m_info.responseException = e;
}
m_newStream.Position = 0;
break;
case SoapMessageStage.AfterDeserialize:
break;
default:
throw new Exception("invalid stage");
}
}
private void SaveStream(string stream) {
DirectoryInfo dir = new DirectoryInfo(Path.Combine(Application.StartupPath, "SOAP debug\\"));
if (!dir.Exists)
dir.Create();
string tempFile = Path.Combine(Application.StartupPath, "SOAP debug\\" + DateTime.Now.ToString("MM-dd-yyyy hh.mm.ss"));
string fileName = tempFile + ".txt";
FileInfo fi = new FileInfo(fileName);
int i = 1;
while (fi.Exists) {
fileName = string.Format("{0} ({1}).txt", tempFile, i);
fi = new FileInfo(fileName);
i++;
}
StreamWriter SR = new StreamWriter(fileName);
SR.Write(stream);
SR.Flush();
SR.Close();
SR.Dispose();
}
This will result in 2 files, 1 for the request and 1 for the request/response
Lars_V_J
August 18th, 2009, 09:41 AM
Thank you. :)
Where exactly should I put the snoop function? Is it like this?
namespace Carl2_360_Integration.UpdatePerson {
using System.Runtime.Serialization;
using System;
.
.
.
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class UpdatePersonServiceClient : System.ServiceModel.ClientBase<Carl2_360_Integration.UpdatePerson.UpdatePersonService>, Carl2_360_Integration.UpdatePerson.UpdatePersonService {
public UpdatePersonServiceClient() {
}
......
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[snoopattribute()]
Carl2_360_Integration.UpdatePerson.UpdatePersonResponse Carl2_360_Integration.UpdatePerson.UpdatePersonService.UpdatePerson(Carl2_360_Integration.UpdatePerson.UpdatePersonRequest request) {
return base.Channel.UpdatePerson(request);
}
[snoopattribute()]
public void UpdatePerson(Carl2_360_Integration.UpdatePerson.CARL2Header CARL2SoapHeader, Carl2_360_Integration.UpdatePerson.PersonType Person) {
Carl2_360_Integration.UpdatePerson.UpdatePersonRequest inValue = new Carl2_360_Integration.UpdatePerson.UpdatePersonRequest();
inValue.CARL2SoapHeader = CARL2SoapHeader;
inValue.Person = Person;
Carl2_360_Integration.UpdatePerson.UpdatePersonResponse retVal = ((Carl2_360_Integration.UpdatePerson.UpdatePersonService)(this)).UpdatePerson(inValue);
}
.......
}
.
.
.
}
I don't know that much about SOAP in C#. I've only used it in C++ using GSOAP before (where debugging is much easier).
dannystommen
August 18th, 2009, 09:50 AM
If it is correct you have something in the client code like next
MyWebservice service = new MyWebserivce();
service.getAll();
Next, right-click 'getAll' -> 'Go to Definition'. Visual Studio will now automatically navigate to the Reference.cs file.
In my example, the code in de reference file looks like
/// <remarks/>
[System.Web.Services.Protocols.SoapRpcMethodAttribute("urn:SectionService#getAll", RequestNamespace="urn:SectionService", ResponseNamespace="urn:SectionService")]
[return: System.Xml.Serialization.SoapElementAttribute("sections")]
public section[] getAll(string token, long entries_on_page, long page_num, out long total_count) {
object[] results = this.Invoke("getAll", new object[] {
token,
entries_on_page,
page_num});
total_count = ((long)(results[1]));
return ((section[])(results[0]));
}
That is the place where the snoopattribute should be placed
[return: System.Xml.Serialization.SoapElementAttribute("sections")]
[snoopattribute()]
public section[] getAll(string token, long entries_on_page, long page_num, out long total_count) {
Your file looks a bit different, but I guess you have it at the right place. Didn't give you any result then?
monalin
August 18th, 2009, 09:52 AM
Theres a neat little application I use for this. It's called soapUI, you can get it at http://soapui.org (http://soapui.org/). It's in java so you'll need to install the framework if you haven't already. But this is by far some of the best software I've used when developing web services using soap. You give it the WSDL url and it does all the work for you. Shows you what it sends as a request (including the headers) gives you the xml for both versions of SOAP. Most importantly for me, it actually returns a friendly error when something is wrong. I love it, makes it easier to debug web services on production machines as well.
Lars_V_J
August 19th, 2009, 02:57 AM
Thank you (both) for your time.
I have been able to get my XML out using Fiddler, but I would like to see if I could get the snooper class to work. That way I can tell the customer to run in debug mode if they get an error that I can't reproduce.
If it is correct you have something in the client code like next
MyWebservice service = new MyWebserivce();
service.getAll();
Sort of. I also have to call an Open() and Close() function.
Next, right-click 'getAll' -> 'Go to Definition'. Visual Studio will now automatically navigate to the Reference.cs file.
....
That is the place where the snoopattribute should be placed
[return: System.Xml.Serialization.SoapElementAttribute("sections")]
[snoopattribute()]
public section[] getAll(string token, long entries_on_page, long page_num, out long total_count) {
Your file looks a bit different, but I guess you have it at the right place. Didn't give you any result then?
No, alas, I don't get any result. But my file looks a lot different. For instance, I don't have things like the [return: .... ] statement.
Lars
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.