千家信息网

WebService的封装技巧有哪些

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章主要为大家分析了WebService的封装技巧有哪些的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习"WebSe
千家信息网最后更新 2026年11月04日WebService的封装技巧有哪些

这篇文章主要为大家分析了WebService的封装技巧有哪些的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习"WebService的封装技巧有哪些"的知识吧。

今天早上起来,想谈谈.NET中的WebService,当然我不想讲什么是WebService,或者怎么用WebService,因为那个大家随便Google一下前100页都能找到答案。今天我想来分享一下我在用WebService中的一些技巧。

一、问题诞生 -- 大部分解决方案的背后总是一些头痛的问题

很早以前就用过传说中的WebService,但一直是用常规的思路在用:创建WebService项目-->写Web服务方法--> 在项目中添加Web引用-->调用Web方法。这样貌似很好,非常符合规范,在一段时间内效果也还可以,但渐渐的随着项目的扩大和同时参与项目的人员增多,就越来越觉得这种常规的方法很是不爽,为什么呢?我每次修改WebService端(添加、删除Web方法,以及修改方法名称),在引用端我都要更新WebService引用,其实是就是更新WSDL文件,很是烦人。

二、化分为合 -- 传说分久必合,合久必分

好吧,既然增加、删除、修改web方法名都会引起WSDL的更新,那么我们索性用一个统一的方法来作为webservice的访问入口吧,然后内部用switch case来区分调用哪个方法,先贴代码吧,再来简单讲讲:

统一访问接口IRemoteCall:

public interface IRemoteCall{      byte[] GeneralCall(string methodName, params byte[] param);}

然后定义一个WebService并实现以上接口(以前还没真在webservice上实现过接口,哈哈):

[WebService(Namespace = http://tempuri.org/)][WebServiceBinding(ConformsTo =   WsiProfiles.BasicProfile1_1)][ToolboxItem(false)]public class BlogService : System.Web.Services.WebService, IRemoteCall{      [WebMethod(EnableSession = true)]      public byte[] GeneralCall(string methodName, params byte[] param)    {          switch (methodName)          {              case "LoadBlog":                 {                     long blogId = Serializer.DeserializeToObject(param);                     BLLBlogArtical ba = new AppBlog().LoadBlog(blogId);                     return Serializer.SerializeToBinary(ba);                 }              case "DeleteBlog":                 {                     //To Do Your Code                     return null;                 }           }     }}

这里为什么要定义接口IRemoteCall呢,主要是为接下来统一调用webservice服务的,所有实现这个接口的webservice类都可以通过GeneralCall来完成调用,待会将webservice访问器的时候会具体讲到,这里主要讲讲这个switch case。

这里我们定义了一个统一的访问入口

byte[] GeneralCall(string methodName,params byte[] param)

意思是:传入要调用的方法名称以及序列化后的参数,返回序列化后的结果。这里为了统一数据,我们均对参数和返回值都序列化成byte数组,即用Serializer.SerializeToBinary(object)来实现,这样所有调用就都统一了格式。

有人可能会提出质疑,这样方法名称都已字符串形式是不是会显得难看,而且字符串容易出错,还没有智能提示?那也好解决,我们可以把方法名称定义成const常量就可以了。这里我对webservice的一个态度是:webservice层就是完成转接和调度工作的,它仅仅起到承接的作用,用了他可以将服务任意分布,所以里面是没有任何逻辑的(逻辑都是被封装在其他dll中的),最多是一些数据转换,所以我采用了这种模糊接口的方式。

三、自定义webservice访问器

上面我们完成了webservice端的工作,接下来就来实现客户端对webservice的灵活调用,这里上面定义的那个IRemoteCall就起到作用了,首先我们定义一个webservice访问器类RemoteCaller,代码如下:

using System;using   System.Collections.Generic;using   System.Text;using   System.Collections;using System.Web.Services.Protocols;  using SharedLib_403;   namespace ITIvy.Shared.RemoteCaller{           ///       /// 远程接口访问器      ///       public class RemoteCaller      {          private string _MethodName;          private byte[] _ParamByte;          private IRemoteCall _Caller;          private ArrayList _Params;           ///           /// 参数列表          ///           public ArrayList Params          {              get { return _Params; }              set { _Params = value; }          }           ///           /// 序列化后的参数          ///           public byte[] ParamByte          {              get { return _ParamByte; }              set { _ParamByte = value; }          }         ///           /// 远程服务方法名称          ///           public string MethodName          {              get { return _MethodName; }              set { _MethodName = value; }          }         ///           /// 远程服务调用接口          ///           public IRemoteCall Caller          {              get { return _Caller; }              set { _Caller = value; }          }           ///           /// 构造          ///           /// Webservice远程接口          public RemoteCaller(IRemoteCall caller)        {              _Caller = caller;              _Params = new ArrayList();          }           ///           /// 调用远程接口        ///           /// 方法名称          /// 参数对象          ///           public byte[] Call(string methodName, object param)        {              try            {                  _MethodName = methodName;                _ParamByte = Serializer.SerializeToBinary(param);                  return _Caller.GeneralCall(_MethodName, _ParamByte);              }              catch (Exception ex)            {                  if (ex is SoapException)                throw new Exception(((SoapException)ex).Detail["Message"].InnerText);                else                      throw ex;              }        }           ///           /// 调用远程接口          ///           /// 方法名称          /// 参数列表          ///           public byte[] Call(string methodName, ArrayList param)          {              try              {                  _MethodName = methodName;                _Params = param;                  _ParamByte = Serializer.SerializeToBinary(_Params);                  return _Caller.GeneralCall(_MethodName, _ParamByte);              }              catch (Exception ex)              {                  if (ex is SoapException)                  throw new Exception(((SoapException)ex).Detail["Message"].InnerText);                  else                      throw ex;            }          }           ///           /// 调用远程接口          ///           /// 方法名称          /// 参数对象数组          ///           public byte[] Call(string methodName, params object[] param)          {              try              {                  foreach (object obj in param)                      _Params.Add(obj);                _MethodName = methodName;                  _ParamByte = Serializer.SerializeToBinary(_Params);                  return _Caller.GeneralCall(_MethodName, _ParamByte);              }              catch (Exception ex)              {                  if (ex is SoapException)                      throw new Exception(((SoapException)ex).Detail["Message"].InnerText);                else                      throw ex;            }          }           ///           /// 调用远程接口          ///           ///           public byte[] Call()          {            try              {                  if (string.IsNullOrEmpty(_MethodName))                      throw new Exception("远程方法不能为空!");                  return _Caller.GeneralCall(_MethodName, _ParamByte);            }              catch (Exception ex)              {                  if (ex is SoapException)                      throw new Exception(((SoapException)ex).Detail["Message"].InnerText);                else                      throw ex;              }        }           ///           /// 调用远程接口        ///           /// 返回值类型        ///         public T Call()          {            byte[] resultByte = Call();            return Serializer.DeserializeToObject(resultByte);        }           ///           /// 调用远程接口          ///           /// 返回值类型          /// 方法名称          /// 参数列表          ///           public T Call(string methodName, ArrayList param)          {              byte[] resultByte = Call(methodName, param);              return Serializer.DeserializeToObject(resultByte);          }           public T Call(string methodName, object param)        {              try            {                  _MethodName = methodName;                  _ParamByte = Serializer.SerializeToBinary(param);                  byte[] resultByte = _Caller.GeneralCall(_MethodName, _ParamByte);                    return Serializer.DeserializeToObject(resultByte);              }            catch (Exception ex)              {                  if (ex is SoapException)                    throw new Exception(((SoapException)ex).Detail["Message"].InnerText);                else                      throw ex;              }        }           ///           /// 调用远程接口          ///           /// 返回值类型          /// 方法名称          /// 参数对象数组          ///           public T Call(string methodName, params object[] param)          {              byte[] resultByte = Call(methodName, param);              return Serializer.DeserializeToObject(resultByte);          }    }}

这个访问器主要是定义了一系列访问接口的重载,利用了c#的泛型更加使接口简单了。哈哈,这个类就能让我们实现一句话调用webservice,相当简洁。注意里面的IRemoteCall属性,就是只要传入实现了该接口的类,就都可以通过该访问器来访问webservice。如何使用该类呢,下面给一个例子吧:


IRemoteCall Caller = new BlogService.BlogService();BLLBlogArtical bllArtical = new RemoteCaller(Caller).Call("LoadBlog", id);

抱歉,说错了,要两句话来调用,但是这里少去了很多数据转换的工作,因为有了泛型,呵呵,而且我可以在RemoteCaller这个访问器类中做很多工作,比如异常处理,权限验证等等。

这个实现方法的核心在于用IRemoteCall接口来规范webservice类的实现方式均为统一GenerateCall,然后 webservice类中通过switch case来将所有方法整合在一起,避免频繁更新WSDL的麻烦,客户端利用IRemoteCall定义一个webservice访问器类 RemoteCaller来提供统一的webservice访问。

这篇文章主要为大家分析了WebService的封装技巧有哪些的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习"WebService的封装技巧有哪些"的知识吧。

接口 方法 名称 参数 统一 技巧 封装 服务 序列 知识 跟着 项目 工作 更新 对象 就是 数据 数组 类型 接下来 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 深圳恒合互联网络科技有限公司 科技股互联网 互联网金融监管科技数据 科技互联网项目 互联网科技有限公司图片 科技企业和互联网企业 互联网科技集团 互联网科技网站 北京三清互联网科技 天速互联网络科技有限公司 栖莱科技互联网股份有限公司 来此购互联网科技有限公司 健康食品互联网创新科技园项目 华夏恒生科技与互联网科技 互联网营销推广黑科技 南京一网一红互联网科技有限公司 扫呗互联网科技有限公司 兰石爱特工业互联网科技分公司 科技信息时代互联网发展 东风日产互联网科技公司叫什么 互联网高科技 哈尔滨大商圈互联网科技有限公司 深圳九邦互联网科技有限公司 金融科技 互联网金融 哈尔滨秒房互联网科技有限公司 银川新华互联网科技学校地址 新兴科技互联网创新大赛颁奖典礼 注册互联网科技公司经营范围大全 爱医互联网络科技 互联网科技实习生岗位
0