如何查看SOAP
前几天在网上找了一圈怎样利用MS SOAP Toolkit中提供的Trace Utility来截取.NET下开发的Web Service的SOAP 消息,刚开始尽管端口都配置对了,但怎么都截取不到,后来终于忘了在哪里看到一眼,需要点小配置才能实现截取。现在说一下:
1- 首先将MSSoapT的端口都配置好:
Local port:9000 (也就是让MSSoapT监听本地9000端口,然后我们就可以通过这个端口来访问Web服务)
Destination:localhost (Web服务的url是http://localhost:1505/WSScore/Service.asmx)
Destination Port:1505 (Web服务的url是http://localhost:1505/WSScore/Service.asmx)
2- 在“调用Web服务的.NET项目”中添加Web引用时,添加url如下:
url是http://localhost:9000/WSScore/Service.asmx (因为我们要MSSoapT来监听这个9000端口,我们访问9000端口上的Web服务,它就会自动定向到1505端口,发送和返回的SOAP消息都从这个9000端口走)
3- 修改“调用Web服务的.NET项目”中的app.config文件,在<configuration>........</configuration>里面添加如下内容:
4- 搞定了。现在就可以查看到SOAP消息了。对于跨平台与Java下应用程序通信时的SOAP截取,只需要配置好MSSoapT的端口就可以了。
另:同样可以用来监听的工具还有tcpTrace,不过中文看到的是乱码~~~建议还是用这个SOAP Toolkit,很好用。
关于下载MSSOAPT工具:Microsoft SOAP Toolkit Version 3 在网上就能方便下载到,另外在Fox Pro 7之后的安装包里也提供了SOAP Toolkit的安装程序和例子。
转自:http://blog.csdn.net/shuaiwang/article/details/1564385
如何使用Soap头
平时写Web Service时经常会对Service的访问进行安全控制,方法很多,这里介绍一下如何用Soap头来进行控制的一例。
第一步,引用需要用到的名称空间
using System;
using System.Xml;
using System.Xml.Serialization;
using System.Web.Services;
using System.Web.Services.Protocols;
第二步,建立自定义的SoapHeader类MySoapHeader
public class MySoapHeader : SoapHeader
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
string _name;
string _passWord;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string Name
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return _name; }
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ _name = value; }
}
public string PassWord
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return _passWord; }
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ _passWord = value; }
}
}
第三步,建立WebSerivce,MyService类有一个MySoapHeader类型的字段公共header,在客户调用CheckHeader之前需要给header付一个新实例,服务器端检验这个实例的成员信息。失败我们抛出一个SoapHeaderException,这个异常的新实例,这里调用两个参数的构造函数。第一个参数是自定义的异常原因,第二个参数我们用SoapException.ClientFaultCode表示客户的调用格式不正确或缺少必要的信息。
[WebService(Namespace = "http://DavidFan.cnblogs.com")]
public class MyService : System.Web.Services.WebService
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
public MySoapHeader header;
[SoapHeader("header", Direction = SoapHeaderDirection.In)]
public string CheckHeader()
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (header == null)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
throw new SoapHeaderException("认证失败", SoapException.ClientFaultCode);
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (header.Name != "admin" || header.PassWord != "admin")
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
throw new SoapHeaderException("认证失败", SoapException.ClientFaultCode);
}
}
//业务逻辑![](https://www.cnblogs.com/Images/dot.gif)
.
return "Something done";
}
}
第四步,客户端进行调用,这里的MySoapHeader,和MyService类即为WSDL工具生成代理类,对应服务端的上两个类。我们首先new 一个MySoapHeader的新实例,然后付个Myservice的新实例的header字段,最后调用CheckHeader这个服务器的方法,CheckHeader方法的header!=null,接着进行Name和PassWord的验证。
客户端try-catch块内首先捕获SoapHeaderException(如果有的话)。然后捕获Exception。好了整个过程只需这几步。
public class ServiceClient
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
protected void ClientMethod(string name, string passWord)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MySoapHeader h = new MySoapHeader();
h.Name = name;
h.PassWord = passWord;
MyService service = new MyService();
service.header = h;
try
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
string retval = service.CheckHeader();
Console.WriteLine("Return:" + retval);
}
catch (SoapHeaderException soapEx)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Console.WriteLine("Soap Header Exception:" + soapEx.Message);
}
catch (Exception ex)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
Console.WriteLine("Exception:" + ex.Message);
}
}
}
转自:http://www.cnblogs.com/DavidFan/archive/2007/04/10/707684.html
如何使用SOAP扩展
SOAP Extension(SOAP扩展)可以封装可重用的功能。比如上一篇讲的通过Soap Header进行服务的访问控制。这篇随笔里我们要利用SOAP扩展做一下对利用Soap Header校验用户身份的封装和解决网友提出的明文传输身份信息不安全的问题。
首先,介绍一下几个相关的类。System.Web.Services.Protocols名称空间下SoapExtension,SoapExtensionAttribute是两个抽象类,不能够实例化,我们要做的事情就是分别继承这两个抽象类,实现自定义类。SoapExtensionAttribute又继承自System.Attribute,说明它是一个Attribute(这个东西不太好翻译,有人译成属性之类,我考虑了一下,感觉翻译成标签更形象,为什么呢?我们用这种类时,一般会在类或方法等上方加[Attribute],这就有点像给东西贴一个标签,告诉别人这个有什么特征,作什么用途)。
我们开始实现自定义的SoapExtension和SoapExtensionAttribute,下边是具体代码,代码中用到了对称加密,我封装了一下MSDN里的提供的一个实现,可以下载源文件在这里/Files/DavidFan/Encryptor.rar。需要引用的名称空间,其中包括我封装的加密类所在的名称空间
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Services.Protocols;
using David.Fan.Encrypt;
下边是自定义的MyExtensionAttribute类,[AttributeUsage(AttributeTargets.Method)]中AttributeTargets.Method是只可以对方法应用,当然你还可以根据Soap扩展的不同功能,设置其它的应用类型。
[AttributeUsage(AttributeTargets.Method)]
public class MyExtensionAttribute : SoapExtensionAttribute
{
int _priority = 1;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public override int Priority
{
get { return _priority; }
set { _priority = value; }
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public override Type ExtensionType
{
get { return typeof(MyExtension); }
}
}
接下来是MyExtension类,继承自SoapExtension
public class MyExtension : SoapExtension
{
//这个override的方法会被调用四次
//分别是SoapMessageStage的BeforeSerialize,AfterSerialize,BeforeDeserialize,AfterDeserialize
public override void ProcessMessage(SoapMessage message)
{
if (message.Stage == SoapMessageStage.AfterDeserialize)//反序列化之后处理
{
bool check = false;
foreach (SoapHeader header in message.Headers)
{
if (header is MySoapHeader)
{
MySoapHeader myHeader = (MySoapHeader)header;
//解密
myHeader.Name = Security.Decrypt(myHeader.Name);
myHeader.PassWord = Security.Decrypt(myHeader.PassWord);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (myHeader.Name == "admin" || myHeader.PassWord == "admin")
{
check = true;
break;
}
}
}
if (!check)
throw new SoapHeaderException("认证失败", SoapException.ClientFaultCode);
}
}
public override Object GetInitializer(Type type)
{
return GetType();
}
public override Object GetInitializer(LogicalMethodInfo info, SoapExtensionAttribute attribute)
{
return null;
}
public override void Initialize(Object initializer)
{
}
}
最后一步如何应用Soap扩展。很简单只需[MyExtensionAttribute]即可。
public class MySoapHeader : SoapHeader
{
string _name;
string _passWord;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public string Name
{
get { return _name; }
set { _name = value; }
}
public string PassWord
{
get { return _passWord; }
set { _passWord = value; }
}
}
[WebService(Namespace = "http://DavidFan.cnblogs.com")]
public class MyService : System.Web.Services.WebService
{
public MySoapHeader header;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
[MyExtensionAttribute]
[SoapHeader("header", Direction = SoapHeaderDirection.In)]
public string CheckHeader()
{
//业务逻辑.
return "Something done";
}
}