WebService开发(二) 如何使用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;

    
public override int Priority
    
{
        
get return _priority; }
        
set { _priority = value; }
    }


    
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);

                    
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]即可。这里用到了SoapHeader,如果你对它不是很熟悉的话,可以参考我的上一篇随笔。
public class MySoapHeader : SoapHeader
{
    
string _name;
    
string _passWord;

    
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;

    [MyExtensionAttribute]
    [SoapHeader(
"header", Direction = SoapHeaderDirection.In)]
    
public string CheckHeader()
    
{
        
//业务逻辑.
        return "Something done";
    }

}

      CheckHeader方法的实现你可以和我上一篇的MyService的CheckHeader方法作一下对比。就看出来Soap扩展的一点好处了。客户端将身份信息加密传送。服务器端拿到加密串进行解密,然后校验,不匹配则摆出异常。
      这里只是对Soap扩展使用的一个特别的简单的举例,当然你还可以发挥,比如压缩消息,日志记录,Trace之类,网上也有很多文章讲。谢谢大家!

posted on 2007-04-11 00:12 David Fan 阅读(3081) 评论(10)  编辑 收藏 网摘 所属分类: WebService

评论

#1楼 2007-04-11 09:05 域名注册[未注册用户]

不错。期待下篇http://***   回复  引用    

#2楼 2007-04-11 09:21 虚拟主机[未注册用户]

你写的太好了谢谢。   回复  引用    

#3楼 2007-07-04 12:56 sekihin      

全部收藏   回复  引用  查看    

#4楼 2007-07-05 07:46 在线代理[未注册用户]

这个好,比上一篇好。   回复  引用    

#5楼 2007-07-18 11:43 迷途小书童[未注册用户]

发现你的public class MyExtension : SoapExtension这东西在你说的这里一点作用也没有...
这个类存在于否在你的这个例子中都好像和程序没什么关系...

请说明一下MyExtension这东东发挥了什么作用????
  回复  引用    

#6楼 2007-07-19 21:45 david fan[未注册用户]

@迷途小书童
[MyExtensionAttribute]
[SoapHeader("header", Direction = SoapHeaderDirection.In)]
public string CheckHeader()
{
//业务逻辑.
return "Something done";
}
  回复  引用    

#7楼 2008-09-04 09:41 James1[未注册用户]

SOAP扩展才能体现到SOAP头的作用。   回复  引用    

#8楼 2009-01-07 16:21 饺子[未注册用户]

使用上面代码好像有点问题哦。

C#

[WebService(Namespace="http://microsoft.com/webservices/")]
public class MyWebService {
// 实现
}
  回复  引用    

#9楼 2009-01-12 10:32 sdf[未注册用户]

学些 谢谢   回复  引用    




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 707781




相关文章:

相关链接:

导航

公告

本Blog内容属本人学习与工作经验之总结。欢迎大家交流经验。请不要发广告链接和与主题无关的回复。谢谢!本人联系方式David.bj(at)hotmail.com
吃完饭就困呀!!
<2007年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

与我联系

搜索

 

留言簿

随笔分类