在将 SOAP 消息发送到 .NET 中的 WebService 之前获取它
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/461744/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get SOAP Message before sending it to the WebService in .NET
提问by Romias
I'm calling an external HTTPS webservice.
我正在调用外部 HTTPS 网络服务。
In order to check what is wrong, the owner needs the SOAP request I'm sending.
为了检查出了什么问题,所有者需要我发送的 SOAP 请求。
I have a web reference and the generated proxy class generated by VS 2008...
我有一个 Web 参考和由 VS 2008 生成的生成的代理类...
Is there a way to see the SOAP message just before sending it?
有没有办法在发送之前查看 SOAP 消息?
I'm thinking in some .net code... because the Sniffers I tried didn't "see" the webservice invocation don't know why.
我正在考虑一些 .net 代码......因为我尝试的嗅探器没有“看到”网络服务调用,不知道为什么。
采纳答案by Kev
What you need is a SoapExtension. There's quite a few good examples here:
你需要的是一个SoapExtension。这里有很多很好的例子:
How do I get access to SOAP response
Getting RAW Soap Data from a Web Reference Client running in ASP.net
从 ASP.net 中运行的 Web 参考客户端获取 RAW Soap 数据
XML Parse error while processing the SOAP response
One of the articles linked to: http://msdn.microsoft.com/en-us/magazine/cc164007.aspx
链接到的文章之一:http: //msdn.microsoft.com/en-us/magazine/cc164007.aspx
Also search SO for: https://stackoverflow.com/search?q=SoapExtension
回答by dizzy128
You can simply serialize the request object, before subtmit, like this:
您可以在提交之前简单地序列化请求对象,如下所示:
var sreq = new SomeSoapRequest();
// ... fill in here ...
var serxml = new System.Xml.Serialization.XmlSerializer(sreq.GetType());
var ms = new MemoryStream();
serxml.Serialize(ms, sreq);
string xml = Encoding.UTF8.GetString(ms.ToArray());
// in xml string you have SOAP request
回答by mting923
You can use IClientMEssageInspector and IEndpointBehavior to fullfill this. I found using this way can capture the exact soap request likely as the fiddler one:
您可以使用 IClientMEssageInspector 和 IEndpointBehavior 来实现这一点。我发现使用这种方式可以捕获可能作为提琴手的确切soap请求:
Create a class like this in the same project:
在同一个项目中创建一个这样的类:
public class ClientMessageInspector : System.ServiceModel.Dispatcher.IClientMessageInspector
{
#region IClientMessageInspector Members
public string LastRequestXml { get; private set; }
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
string requestHeaderName = request.Headers.Action.Replace("urn:#",string.Empty);
LastRequestXml = request.ToString();
string serializedRequestFile = string.Format(requestHeaderName + "_request_{0}.xml", DateTime.Now.ToString("yyyyMMddHHmmss"));
string exportedFolder = ConfigurationManager.AppSettings["SubmittedRequestXmLocation"];
printSoapRequest(request, exportedFolder, serializedRequestFile);
return request;
}
public void printSoapRequest(System.ServiceModel.Channels.Message request, string exportedFolder, string fileName)
{
if (exportedFolder.Equals(string.Empty))
return;
if (!Directory.Exists(exportedFolder))
{
Directory.CreateDirectory(exportedFolder);
}
string exportedFile = string.Format("{0}\{1}", exportedFolder, fileName);
if (File.Exists(exportedFile))
{
File.Delete(exportedFile);
}
string strRequestXML = request.ToString();
XDocument xDoc = XDocument.Parse(strRequestXML);
XmlWriter xw = XmlWriter.Create(exportedFile);
xDoc.Save(xw);
xw.Flush();
xw.Close();
LogOutput("Request file exported: " + exportedFile);
}
}
public class CustomInspectorBehavior : IEndpointBehavior
{
private readonly ClientMessageInspector clientMessageInspector = new ClientMessageInspector();
public string LastRequestXml
{
get { return clientMessageInspector.LastRequestXml; }
}
public string LastResponseXml
{
get { return clientMessageInspector.LastRequestXml; }
}
public void AddBindingParameters(
ServiceEndpoint endpoint,
System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(clientMessageInspector);
}
}
Then you can call it like the following:
然后你可以像下面这样调用它:
ProxyClass _class = new ProxyClass();
var requestInterceptor = new CustomInspectorBehavior();
_client.Endpoint.Behaviors.Add(requestInterceptor);
When you call the service method, it will automatically execute the interceptor and print the output. Using this way you can also manipulate the soap message before sending to the server!
当你调用服务方法时,它会自动执行拦截器并打印输出。使用这种方式,您还可以在发送到服务器之前操作soap 消息!
回答by Collin Anderson
Add this to the element of your web.config or App.config file. It will create a trace.log file in your project's bin/Debug folder. Or, you can specify an absolute path for the log file using the initializeData attribute.
将此添加到您的 web.config 或 App.config 文件的元素中。它将在项目的 bin/Debug 文件夹中创建一个 trace.log 文件。或者,您可以使用 initializeData 属性指定日志文件的绝对路径。
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="System.Net" maxdatasize="9999" tracemode="protocolonly">
<listeners>
<add name="TraceFile" type="System.Diagnostics.TextWriterTraceListener" initializeData="trace.log"/>
</listeners>
</source>
</sources>
<switches>
<add name="System.Net" value="Verbose"/>
</switches>
</system.diagnostics>
It warns that the maxdatasize and tracemode attributes are not allowed, but they increase the amount of data that can be logged, and avoid logging everything in hex.
它警告不允许使用 maxdatasize 和 tracemode 属性,但它们会增加可以记录的数据量,并避免以十六进制记录所有内容。
回答by Steven Hunt
If you work in a more restricted environment and don't have the luxury of using an application like Fiddler, you can do the following:
如果您在更受限制的环境中工作并且没有使用像 Fiddler 这样的应用程序的奢侈,您可以执行以下操作:
- Generate your web reference as usual.
- Write code to perform whatever web method call you're going to me.
- Create a new ASP .NET project of your choice, I went with MVC 4.
- Create a handler or controller/action, and extract the request stream like this:
- 像往常一样生成您的网络参考。
- 编写代码来执行您要给我的任何 Web 方法调用。
- 创建一个您选择的新 ASP .NET 项目,我选择了 MVC 4。
- 创建一个处理程序或控制器/动作,并像这样提取请求流:
using (var reader = new System.IO.StreamReader(Request.InputStream))
{
result = reader.ReadToEnd();
}
using (var reader = new System.IO.StreamReader(Request.InputStream))
{
result = reader.ReadToEnd();
}
- Put a breakpoint on it and run it in debug mode.
- On your client, set the Url of the SOAP request to your new controller/handler.
- Run your client. You should catch the breakpoint on your web app with your SOAP message.
- 在它上面放置一个断点并在调试模式下运行它。
- 在您的客户端上,将 SOAP 请求的 Url 设置为您的新控制器/处理程序。
- 运行你的客户端。您应该使用 SOAP 消息捕获 Web 应用程序上的断点。
It's not an ideal or pretty solution, but if you are working in a moderately restricted environment, it gets the job done.
这不是一个理想或漂亮的解决方案,但如果您在适度受限的环境中工作,它就可以完成工作。

