描述:

最近一个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. Java集合和泛型

    集合 常用的集合有ArrayList,TreeSet,HashMap,HashSet. ArrayList 最常用的集合,每次插入都在后面追加元素. TreeSet 以有序状态保持并可防止重复.当你需 ...

  2. 团队作业——Alpha冲刺 11/12

    团队作业--Alpha冲刺 冲刺任务安排 杨光海天 今日任务:预览界面布局实现,并留下交互接口 明日任务:预览界面中自定义保存的实现 郭剑南 今日任务:尝试解决Python编写程序无法在Android ...

  3. 第二次项目冲刺(Beta版本)

    第二次项目冲刺(Beta版本) 团队作业7--第二次项目冲刺(Beta版本)day1 http://www.cnblogs.com/wj946/p/8017787.html 团队作业7--第二次项目冲 ...

  4. python第三十九课——面向对象(二)之初始化属性

    设计Car类,初始化属性speed,提供一个run函数 import time class Car: def __init__(self,speed): self.speed=speed #将Road ...

  5. 【转】Android7.0适配心得

    本文出自:贾鹏辉的技术博客(http://www.devio.org) http://www.devio.org/2016/09/28/Android7.0%E9%80%82%E9%85%8D%E5% ...

  6. OpenCV——使用多边形包围轮廓

  7. (三) DRF 序列化

    一.单表的GET和POST: 使用serializers序列化,针对每一个表,需要单独写函数.一般会写在views.py里面,但是这样做,会导致整个文件代码过长.需要分离出来! 在app01(应用名) ...

  8. QT的常用对话框的应用

    QMessageBox类提供了常用的弹出式对话框:提示.警告.错误.询问.关于对话框 需要添加头文件 #include <QMessageBox> MESSAGE  是要是显示的字符串 v ...

  9. web.py利用模板的详细步骤

    <python网络编程学习笔记(10):webpy框架>(http://www.cnblogs.com/xiaowuyi/archive/2012/11/15/2771099.html#3 ...

  10. 编写Linux脚本

    下面是重新启动Linux下某进程的shell脚本.以tomcat进程为例: #!/bin/sh pid=`ps -ef|grep tomcat|grep -v grep|awk '{print $2} ...