iservice封装有哪些方法_对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(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;
///
/// 远程接口访问器
///
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访问。哈哈哈
iservice封装有哪些方法_对WebService的一些封装技巧总结相关推荐
- iservice封装有哪些方法_总结WebService的一些封装技巧
今天早上起来,想谈谈.NET中的WebService,当然我不想讲什么是WebService,或者怎么用WebService,因为那个大家随便Google一下前100页都能找到答案.今天我想来分享一下 ...
- iservice封装有哪些方法_请问这段Java代码能不能封装成一个方法
问题描述 这段代码在我的项目中经常会被使用到,想要把它封装成一个方法以达到减少代码量的目的,但由于本人是个菜鸟没能做到,希望有心的大神提供下思路.在此先行拜谢了. 目的:想将hardwareServi ...
- iservice封装有哪些方法_软件主要有哪几种封装方法
展开全部 常用的软件封包形式主要有以下几个形式 Inno Setup InstallShield NSIS Microsoft Windows Installer WISE QUOTE: 一636f7 ...
- lisp封装为vlx方法_将VLDCL的FAS编译进VLX
伴随着VLDCL包提供的,有VLDCL.VLX文件,里面有完整的VLDCL对外输出函数集合,供用户在设计.运行和调试基于VLDCL的程序前加载,保证能够正确驱动.但用户程序最终发布时,往往希望编译成一 ...
- lisp封装为vlx方法_将别的VLX打包进自己的VLX(测试与实战)
本帖最后由 自贡黄明儒 于 2015-4-9 11:07 编辑 将别的VLX打包进自己的VLX(测试与实战) highflybird曰:DynamicWrapperX 是一个ActiveX部件,它可以 ...
- php 公众号验证回调方法_微信公众号运营的技巧和方法?
微信公众号+朋友圈+社群,已经成为大多数企业的营销标准.我们真的没有理由不选择用户数量最多.粘性最强的营销媒体.不管一个品牌有多小,他都有自己的品牌,每个人都有不同的方法和技巧.接下来,我将与大家分享 ...
- 封装 电流密度 重布线_半导体封装及其制造方法与流程
本发明实施例涉及一种半导体封装及其制造方法. 背景技术: 业界已知使用连接在横向上间隔开的结合垫与焊料凸块的重布线层来制作微电子导体装置,例如半导体装置.此种装置是晶片级芯片规模封装(waferlev ...
- w3c的ajax操作函数,关于ajax的使用方法_例题、ajax的数据处理
AJAX 的 关于ajax的使用方法_例题.ajax的数据处理 需要注意的是,调用的封装的数据库,和jQuery的保存地址 一.注册 (1)写文本框来进行用户名的验证 //这个使用来显示提示信息的 ( ...
- JQuery封装的ajax方法
JQuery封装的ajax方法 JQuery封装的ajax优势:简单方便,已做好浏览器兼容性处理. 1.$.post方法 $.post(url[,data][,callback][,type]) ...
最新文章
- 使用Nginx-rtmp-module搭建hls直播
- 清华朱民:数据「资产化」,将是大变革!
- Nginx配置——防盗链
- 取IDE当前文档所在项目的目录[vs.net2008]
- PostgreSQL 10.1 手册_部分 II. SQL 语言_第 11 章 索引_11.5. 组合多个索引
- php原生session,利用Memcached在php下实现session机制 替换PHP的原生session支持
- 基金理财系列6 之指数基金
- 华为鸿蒙系统是指芯片吗_没有了芯片,华为能靠鸿蒙OS系统打出差异化吗?
- 190702每日一句 孤独之前是迷茫,孤独之后是成长
- 『电脑技巧』破解Win7/Win8登录密码
- AJAX学习摘记——客户端访问WebService(上)
- 手持式以太网测试仪RFC2544测试演示
- c语言中until的用法,until的用法总结
- 赵鑫:强化学习在京东广告序列推荐中的应用
- python roundup 和 rounddown
- 51单片机LCD显示温度与串口接受温度
- 智慧公厕,让厕所也成为城市文明的一部分
- 将一个长字串分拆为多条记录
- 2021-06-01-《图解HTTP》笔记
- 在FreeBSD下安装subversion