描述:

最近一个winform项目刚开发完成。采用c/s架构。闲来把一些技术点整理下了。

做项目之前调研了客户的电脑 .客户端机子性能一般,而且都是基于xp。

这些客观存在的问题,注定了实现过程中必须考虑客户端性能,frmaework版本等因素。

基于这些原因 我选择了2.0版本的 webservice。没有选择3.5版本的wcf,原因主要还是担心客户端环境的复杂度。使用2.0会保险点。(妈蛋,2.0写的各种蛋疼,没有语法糖很不爽)

细节:

1.首先肯定是要通过工具生成WSProxy.

2.webservice是基于请求request 和 返回 response来交互的。我将传输对象封装成实体,

RequestHead 对象是请求头,存放基础信息。
XObject 是传输的对象。原先是直接用object代替的。但是我们项目数据量比较大,所以对ojbect进行封装了,XObject在传输过程中主要是负责解析的。目前解析有三种形式:XML(ws标准), Json ,字节,目前我们采用的是json。
   /// <summary>
/// 请求参数
/// </summary>
[GeneratedCode("System.Xml", "4.0.30319.18408")]
[Serializable]
[DebuggerStepThrough]
[DesignerCategory("code")]
[XmlType(Namespace = "http://tempuri.org/")]
public class Request
{
private readonly RequestHead headField = new RequestHead();
private readonly XObject xbodyField = new XObject(); /// <summary>
/// 请求的 头信息
/// </summary>
public RequestHead Head
{
get { return headField; }
set { headField.CopyFrom(value); }
} /// <summary>
/// 请求的 具体值
/// </summary>
[XmlIgnore, SoapIgnore, JsonIgnore]
public object Body
{
get { return xbodyField.Value; }
set { xbodyField.Value = value; }
} /// <summary>
////// </summary>
public XObject XBody
{
get { return xbodyField; }
set { xbodyField.CopyFrom(value); }
}
} /// <summary>
/// 请求 头信息
/// </summary>
[GeneratedCode("System.Xml", "4.0.30319.18408")]
[Serializable]
[DebuggerStepThrough]
[DesignerCategory("code")]
[XmlTypeAttribute(Namespace = "http://tempuri.org/")]
public class RequestHead
{
public RequestHead()
{
RequestID = Guid.NewGuid().ToString().ToUpper();
} /// <summary>
/// 用户ID
/// </summary>
//[XmlAttribute]
public UserInfo User { get; set; }
/// <summary>
/// 请求GUID
/// </summary>
//[XmlAttribute]
public string RequestID { get; set; } /// <summary>
/// 请求的函数
/// </summary>
//[XmlAttribute]
public string Method { get; set; }
/// <summary>
/// 异步请求
/// </summary>
//[XmlAttribute]
public bool IsAsync { get; set; } /// <summary>
/// 从 另外的对象 复制属性值
/// </summary>
public void CopyFrom(RequestHead head)
{
//UserID = head == null ? string.Empty : head.UserID;
RequestID = head == null ? string.Empty : head.RequestID;
//ClientIP = head == null ? string.Empty : head.ClientIP;
Method = head == null ? string.Empty : head.Method;
IsAsync = head == null ? false : head.IsAsync;
User = head == null ? null : head.User;
} }
  /// <summary>
/// 响应结果
/// </summary>
[GeneratedCode("System.Xml", "4.0.30319.18408")]
[Serializable]
[DebuggerStepThrough]
[DesignerCategory("code")]
[XmlTypeAttribute(Namespace = "http://tempuri.org/")]
public class Response
{
private readonly ResponseHead headField = new ResponseHead();
private readonly XObject xbodyField = new XObject(); /// <summary>
/// 响应的 头信息
/// </summary>
public ResponseHead Head
{
get { return headField; }
set { headField.CopyFrom(value); }
} /// <summary>
/// 响应的 具体值
/// </summary>
[XmlIgnore, SoapIgnore, JsonIgnore]
public object Body
{
get { return xbodyField.Value; }
set { xbodyField.Value = value; }
} /// <summary>
////// </summary>
public XObject XBody
{
get { return xbodyField; }
set { xbodyField.CopyFrom(value); }
} public Response(){ }
public Response(RequestHead requestHead)
{
this.Head.UserID = requestHead.User.UserID;
this.Head.RequestID = requestHead.RequestID;
}
} /// <summary>
/// 响应 头信息
/// </summary>
[GeneratedCode("System.Xml", "4.0.30319.18408")]
[Serializable]
// [DebuggerStepThrough]
[DesignerCategory("code")]
[XmlTypeAttribute(Namespace = "http://tempuri.org/")]
public class ResponseHead
{
public ResponseHead()
{
ResultCode = ResultCode.UnKown;
} /// <summary>
/// 请求版本
/// </summary>
[XmlAttribute]
public string Version { get; set; }
/// <summary>
/// 用户ID
/// </summary>
[XmlAttribute]
public string UserID { get; set; }
/// <summary>
/// 请求GUID
/// </summary>
[XmlAttribute]
public string RequestID { get; set; } /// <summary>
/// 结果标志
/// </summary>
[XmlAttribute]
public ResultCode ResultCode { get; set; }
/// <summary>
/// 结果标志
/// </summary>
[XmlAttribute]
public string ResultNo { get; set; }
/// <summary>
/// 失败信息
/// </summary>
[XmlAttribute]
public string ResultMsg { get; set; }
/// <summary>
/// 时间戳
/// </summary>
[XmlAttribute]
public string Timestamp { get; set; } /// <summary>
/// 利用请求给结果的头部信息赋值
/// </summary>
/// <param name="header">请求头对象</param>
public void SetHeaderInfo(RequestHead header)
{
this.RequestID = header.RequestID;
this.UserID = header.User.UserID;
}
/// <summary>
/// 设置结果信息
/// </summary>
/// <param name="resultcode">结果类型</param>
/// <param name="resultno">失败代号</param>
/// <param name="resultmsg">失败信息</param>
public void SetResult(ResultCode resultcode, long resultno, string resultmsg)
{
this.Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fffff");
this.ResultCode = resultcode;
this.ResultNo = resultno.ToString();
if (!string.IsNullOrEmpty(resultmsg)) this.ResultMsg = resultmsg;
} /// <summary>
/// 设置结果信息
/// </summary>
/// <param name="resultcode">结果类型</param>
/// <param name="resultno">失败代号</param>
/// <param name="resultmsg">失败信息</param>
public void SetFailResult(ResultCode resultcode, string resultno, string resultmsg)
{
this.Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fffff");
this.ResultCode = resultcode;
this.ResultNo = resultno;
if (!string.IsNullOrEmpty(resultmsg)) this.ResultMsg = resultmsg;
} /// <summary>
/// 从 另外的对象 复制属性值
/// </summary>
public void CopyFrom(ResponseHead head)
{
Version = head == null ? string.Empty : head.Version;
UserID = head == null ? string.Empty : head.UserID;
RequestID = head == null ? string.Empty : head.RequestID;
ResultCode = head == null ? ResultCode.Fail : head.ResultCode;
ResultNo = head == null ? string.Empty : head.ResultNo;
ResultMsg = head == null ? string.Empty : head.ResultMsg;
Timestamp = head == null ? string.Empty : head.Timestamp;
}
}

3.创建ws基类,利用模板模式能够很好的抽象出方法的共性。

    /// <summary>
/// WebService基类,所有继承者必须实现Request方法
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
public abstract class WSBase : WebService
{
///// <summary>
///// IP白名单
///// </summary>
internal static string IPList = ""; /// <summary>
/// WebService基类构造函数
/// </summary>
static WSBase()
{ if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["IPList"].ToString()))
IPList = ConfigurationManager.AppSettings["IPList"];
} /// <summary>
/// 接收用户请求并返回相应结果
/// </summary>
/// <param name="request">请求对象</param>
[WebMethod(EnableSession = false)]
public Response Request(Request request)
{
try
{
var response = new Response(); if (!Auth(request.Head))
{ } //判断反序列化是否成功
if (request == null)
{ } //todo:安全校验iplist return RequestDeal(request,response);
}
catch (SoaException soaExp)
{
Log.Error(soaExp.Message,soaExp); response.Head.SetHeaderInfo(request.Head);
response.Head.SetResult(ResultCode.Fail, soaExp.ResultNo, soaExp.Message);
return response;
}
catch (Exception exp)
{
Log.Error(exp.Message, exp);
response.Head.SetHeaderInfo(request.Head);
response.Head.SetResult(ResultCode.Fail, , exp.Message);
return response;
}
} /// <summary>
/// 请求处理方法
/// </summary>
protected abstract Response RequestDeal(Request request, Response response); /// <summary>
/// 通过代理,获取客户端真实的IP地址
/// </summary>
/// <returns>返回客户端真实的IP地址</returns>
private static string GetClientIPAddress()
{return ip;
} /// <summary>
/// 授权
/// </summary>
/// <returns></returns>
private bool Auth(RequestHead head)
{
return true;
} }

实现类中实现 RequestDeal方法

    [WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消注释以下行。
// [System.Web.Script.Services.ScriptService]
public class TktService : WSBase
{
protected override Response RequestDeal(Request request,Response response)
{ try
{
object result = null;
switch (request.Head.Method)
{ case "Np":
new NpService().Np((HashRequest)request.Body, ref response);
break;
//case "GetSpByGuest":
// new HjdService().GetByGuestCard((HashRequest)request.Body, ref response);
// break;
case "GetSpBy": //根据查询对象或者售票信息
new BuPiaoService().GetSpBy((BuPiaoQModel)request.XBody, ref response);
break;
} response.Head.SetHeaderInfo(request.Head);
response.Head.Timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fffff"); } catch (Exception ex)
{
string logMsg = string.Format("ts服务出错: 函数名:{0},错误消息:{1}", request.Head.Method,ex.Message);
response.Head.SetFailResult(ResultCode.Fail, "", logMsg );
Log.Error(logMsg,ex);
}
return response;
} }

4.客户端如何调用服务端方法

2.0环境下没有泛型,只能用object代替

public  class WSClient
{ public static string CrsServiceURL = "CrsServiceURL";
public static string TktServiceURL = "TktServiceURL"; public static Response GetOData(string url, string method, object requestBody, UserInfo user)
{
WSProxy proxy = new WSProxy();
proxy.Url = WSProxy.GetWebServiceUrl(url); Request request = new Request();
request.Head.Method = method;
request.Head.User = user;
request.Body = requestBody; return proxy.Request(request);
}
public static object GetCrsData(string method, object requestBody, UserInfo user )
{
var response =GetOData(OtherServiceURL, method, requestBody,user);
//if (response.Head.ResultCode==ResultCode.Success)
//{
return response.Body; }
public static object GetTsData(string method, object requestBody, UserInfo user )
{ var response = GetOData(TktServiceURL, method, requestBody,user);
        return   response.Body;
 } }

5.OK基本就是这样。目前服务大概80多个,测试服务是非常耗时的。为了实现服务的本地调试,我们写了个类,针对开发过程中不启用服务直接调用方法的class。

项目过程中,前期对技术的难点、消耗的时间最好都做个有效的评估。尽量在前期把技术问题处理掉。

扩展webservice的更多相关文章

  1. WebService之JDK中wsimport命令

    1.编写WebService类,使用@WebService注解 package test; import javax.jws.WebService; @WebService public class ...

  2. C# Webservice 解决在运行配置文件中指定的扩展时出现异常。 ---> System.Web.HttpException: 超过了最大请求长度问

    摘自: http://blog.csdn.net/gulijiang2008/article/details/4482993 请在服务器端配置 方法一: 在通过WebService处理大数据量数据时出 ...

  3. SOAP扩展PHP轻松实现WebService

    最近在一个PHP项目中对接外部接口涉及到WebService,搜索引擎上相关文章不是很多,找到的大都是引用一个号称很强大的开源软件 NuSOAP(下载地址:http://sourceforge.net ...

  4. 开始webservice了

    一.WebService到底是什么 一言以蔽之:WebService是一种跨编程语言和跨操作系统平台的远程调用技术. 所谓跨编程语言和跨操作平台,就是说服务端程序采用java编写,客户端程序则可以采用 ...

  5. Spring WebService入门

    Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述.发布.发现.协调和配置这些应用程序,用于开发分布 ...

  6. 浅谈WebService的版本兼容性设计

    在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...

  7. WebService 概念和工作原理(一)

    今天我们一起来学习WebService.它到底是干啥用的? Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集) ...

  8. Java使用MyEclipse构建webService简单案例

     什么是WebServices? 它是一种构建应用程序的普遍模型,可以在任何支持网络通信的操作系统中实施运行;它是一种新的web应用程序分支,是自包含.自描述.模块化的应用,可以发布.定位.通过web ...

  9. asp.net webservice返回json问题

    使用jQuery $.ajax方法请求webservice 一.方法返回值为string,将json格式的字符串返回 设置contentType为"application/json;char ...

随机推荐

  1. 分布式全局ID生成器设计

    项目是分布式的架构,需要设计一款分布式全局ID,参照了多种方案,博主最后基于snowflake的算法设计了一款自用ID生成器.具有以下优势: 保证分布式场景下生成的ID是全局唯一的 生成的全局ID整体 ...

  2. Windows Server 2012上安装.NET Framework 3.5

    引用:https://jingyan.baidu.com/article/14bd256e26b714bb6d26128a.html 装不成功后网上搜到很多相同的问题,都尝试过没解决到 用PowerS ...

  3. linux 的常用命令---------第三阶段

    用户管理 为什么需要用户? 答:linux是一个多用户系统 权限管理(使之权限最小化) 用户:它是对系统中的资源做归属的 : 用户组:在用户组中包含一个或者多个用户,每个用户都同时拥有用户组的权限. ...

  4. elk平台定制化查询规则

    一.查询某IP在某时间内TOP10的请求 步骤: 点击“Visualize”选项卡 创建“Data table” 点击“From a new search” 下拉选择“F5-access” 在“buc ...

  5. 多Tomcat多JDK版本的Window服务添加配置方式

    本文所讲的配置方式只适合Windows系统,所牵扯的软件2个解压的jdk,2个解压的tomcat. 1.环境初始化 将两个jdk和tomcat解压到我们指定的目录下.修改两个tomcat的端口:必须修 ...

  6. Python2.7-codecs

    codecs 自然语言编码转换模块 模块内的主要方法如下: codecs.encode(obj[, encoding[, errors]]):对obj用encoding编码codecs.decode( ...

  7. Scrapy 框架(二)数据的持久化

    scrapy数据的持久化(将数据保存到数据库) 一.建立项目 1.scrapy startproject dushu 2.进入项目 cd dushu 执行:scrapy genspider -t cr ...

  8. Application Constants

    Application: Application类是Android框架中提供的一个类.本身程序员不需要创建它,只需要继承它既可.并在manifest中进行注册. 它给我们提供了一个一般不会被销毁的全局 ...

  9. P3084 [USACO13OPEN]照片Photo

    题目描述 农夫约翰决定给站在一条线上的N(1 <= N <= 200,000)头奶牛制作一张全家福照片,N头奶牛编号1到N. 于是约翰拍摄了M(1 <= M <= 100,00 ...

  10. python:'ascii' codec can't encode character

    python默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报这样的错,python没办法处理非ascii编码的, 此时需要自己设置python的默认编码,一般设置为u ...