基于Web Service的客户端框架搭建三:代理层(Proxy)
前言
代理层的主要工作是调用Web Service,将在FCL层序列化好的Json数据字符串Post到Web Service,然后获得Reponse,再从响应流中读取到调用结果Json字符串,在Dispatcher反序列化成数据对象,在UI层呈现出来。
HttpHelper类(参考自:http://blog.csdn.net/eriloan/article/details/7000790)
刚开始是直接在Proxy类中直接写的Post方法,后来看到这篇帖子,将Http相关的部分封装成了工具类HttpHelper。原帖中还包含了使用TCPSocket发送请求调用WebService的内容。
namespace ProjectmsMGT_Proxy
{
public class HttpHelper
{
/// <summary>
/// Http请求URL
/// </summary>
public string Url { set; get; } /// <summary>
/// 请求参数Key(约定服务方法参数名同名)
/// 在使用Post方式向服务器端发送请求的时候,请求数据中包含了参数部分,参数部分我们需要告诉WebService接口方法,实参要传给的接口方法行参名,由RequestParaKey指定
/// 当然当接口方法有多个形参时,就不建议单独设计这样一个属性,直接在sendMsg中添加,此处只是为了突出RequestParaKey的重要性
/// </summary>
public string RequestParaKey { set; get; } /// <summary>
/// 证书文件路径
/// </summary>
public string CertificateFilePath { set; get; } /// <summary>
/// 证书文件口令
/// </summary>
public string CertificateFilePwd { set; get; } /// <summary>
/// 构造函数,不使用证书
/// </summary>
/// <param name="url"></param>
/// <param name="requestParaKey"></param>
public HttpHelper(string url, string requestParaKey)
{
this.Url = url;
this.RequestParaKey = requestParaKey;
} /// <summary>
/// 构造函数,使用证书
/// </summary>
/// <param name="url"></param>
/// <param name="requestParaKey"></param>
/// <param name="certFilePath"></param>
/// <param name="certFilePwd"></param>
public HttpHelper(string url, string requestParaKey, string certFilePath, string certFilePwd)
{
this.Url = url;
this.RequestParaKey = requestParaKey;
this.CertificateFilePath = certFilePath;
this.CertificateFilePwd = certFilePwd;
} /// <summary>
/// 使用Get方式,发送Http请求
/// </summary>
/// <param name="methodName">所请求的接口方法名</param>
/// <param name="isLoadCert">是否加载证书</param>
/// <returns>响应字符串</returns>
public string CreateHttpGet(string methodName, bool isLoadCert)
{
HttpWebRequest request = CreateHttpRequest(methodName, @"GET", isLoadCert); return CreateHttpResponse(request);
} /// <summary>
/// 使用Post方式,发送Http请求
/// </summary>
/// <param name="methodName">所请求的接口方法名</param>
/// <param name="sendMsg">请求参数(不包含RequestParaKey部分)</param>
/// <param name="isLoadCert">是否加载证书</param>
/// <returns>响应字符串</returns>
public string CreateHttpPost(string methodName, string sendMsg, bool isLoadCert)
{
//创建Http请求
HttpWebRequest request = CreateHttpRequest(methodName, @"POST", isLoadCert);
if (null != sendMsg && !"".Equals(sendMsg))
{
//添加请求参数
AddHttpRequestParams(request, sendMsg);
} //获得响应
return CreateHttpResponse(request);
} /// <summary>
/// 将请求参数写入请求流
/// </summary>
/// <param name="request"></param>
/// <param name="sendMsg"></param>
private void AddHttpRequestParams(HttpWebRequest request, string sendMsg)
{
//将请求参数进行URL编码
string paraUrlCoded = System.Web.HttpUtility.UrlEncode(RequestParaKey) + "=" +
System.Web.HttpUtility.UrlEncode(sendMsg); byte[] data = Encoding.UTF8.GetBytes(paraUrlCoded);
request.ContentLength = data.Length;
Stream requestStream = null;
using (requestStream = request.GetRequestStream())
{
//将请求参数写入流
requestStream.Write(data, , data.Length);
} requestStream.Close();
} /// <summary>
/// 创建HttpRequest
/// </summary>
/// <param name="methodName"></param>
/// <param name="requestType">POST或者GET</param>
/// <param name="isLoadCert"></param>
/// <returns>HttpWebRequest对象</returns>
private HttpWebRequest CreateHttpRequest(string methodName, string requestType, bool isLoadCert)
{
HttpWebRequest request = null;
try
{
string requestUriString = Url + "/" + methodName;
request = (HttpWebRequest)WebRequest.Create(requestUriString);
if (isLoadCert)
{
//创建证书
X509Certificate2 cert = CreateX509Certificate2();
//添加证书认证
request.ClientCertificates.Add(cert);
}
request.KeepAlive = true;
request.ContentType = "application/x-www-form-urlencoded";
request.Method = requestType;
}
catch (Exception)
{
//Console.WriteLine("创建HttpRequest失败。原因:" + e.Message);
request = null;
} return request;
} /// <summary>
/// 创建请求响应
/// </summary>
/// <param name="request"></param>
/// <returns>响应字符串</returns>
private string CreateHttpResponse(HttpWebRequest request)
{
String str;
HttpWebResponse response = null;
Stream responseStream = null;
XmlTextReader responseReader = null;
try
{
using (response = (HttpWebResponse)request.GetResponse())
{
//获得响应流
responseStream = response.GetResponseStream();
responseReader = new XmlTextReader(responseStream);
responseReader.MoveToContent();
str = responseReader.ReadInnerXml();
}
}
catch (Exception e)
{
str = "[{\"Rescode\":\"0\",\"Resmsg\":\"通信失败。原因:" + e.Message + "\"}]";
}
finally
{
if (null != response)
{
responseReader.Close();
responseStream.Close();
response.Close();
}
} return str;
} /// <summary>
/// 创建证书
/// </summary>
/// <returns>X509Certificate2对象</returns>
private X509Certificate2 CreateX509Certificate2()
{
X509Certificate2 cert = null;
try
{
cert = new X509Certificate2(CertificateFilePath, CertificateFilePwd);
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(ServerCertificateValidationCallback);
}
catch (Exception)
{
//Console.WriteLine("创建X509Certificate2失败。原因:" + e.Message);
cert = null;
}
return cert;
} /// <summary>
/// Verifies the remote Secure Sockets Layer (SSL) certificate used for authentication
/// </summary>
/// <param name="obj">An object that contains state information for this validation</param>
/// <param name="cer">The certificate used to authenticate the remote party</param>
/// <param name="chain">The chain of certificate authorities associated with the remote certificate</param>
/// <param name="error">One or more errors associated with the remote certificate</param>
/// <returns>A Boolean value that determines whether the specified certificate is accepted for authentication</returns>
private bool ServerCertificateValidationCallback(object obj, X509Certificate cer, X509Chain chain, System.Net.Security.SslPolicyErrors error)
{
return true;
}
}
}
HttpHelper中把SSL证书的部分也包含进来,但是证书认证机制部分ServerCertificateValidationCallback还没设计,各位大神可以自行发挥。
代理类Proxy
有了HttpHelper之后,代理类的代码就比较明了了。
namespace ProjectmsMGT_Proxy
{
public class ProjectmsProxy
{
private readonly string Url = "http://59.68.29.106:8087/IFT_Project.asmx";//通过配置文件获取Web Service地址
private readonly string requestParaKey = "paramaters";//服务端所有接口函数统一的参数名
private HttpHelper httpHelper; public ProjectmsProxy()
{
//初始化
Initialize();
} private void Initialize()
{
httpHelper = new HttpHelper(this.Url, this.requestParaKey);
} /// <summary>
/// 使用Get方式调用WebService,不带参数
/// </summary>
/// <param name="methodName"></param>
/// <param name="parasJsonStr"></param>
/// <param name="requestType"></param>
/// <returns></returns>
public string Excute(string methodName, string parasJsonStr, string requestType)
{
return httpHelper.CreateHttpGet(methodName, false);
} /// <summary>
/// 默认使用Post方式调用WebService,带参数
/// </summary>
/// <param name="methodName"></param>
/// <param name="parasJsonStr"></param>
/// <returns></returns>
public string Excute(string methodName, string parasJsonStr)
{
return httpHelper.CreateHttpPost(methodName, parasJsonStr, false);
} /// <summary>
/// 默认使用Post方式调用WebService,不带参数
/// </summary>
/// <param name="methodName"></param>
/// <returns></returns>
public string Excute(string methodName)
{
return httpHelper.CreateHttpPost(methodName, null, false);
}
}
}
Proxy中重载了Excute方法,三个参数的表示使用Get方式调用WebService(因为不建议在Get方式下传参给Web Service),两个参数和一个参数的Excute默认是使用Post方式带参数和不带参数的情况。
总结
将方法名作为参数Post到Web Service可以减少很多重复代码,不需要对服务端的每个接口函数做写一个代理函数,这是使用Post方式比使用添加Web服务引用方式更加灵活。
基于Web Service的客户端框架搭建三:代理层(Proxy)的更多相关文章
- 基于Web Service的客户端框架搭建四:终结篇
前言 这是这个系列的终结篇,前面3个博客介绍了一下内容: 1.使用Http Post方式调用Web Service 2.客户端框架之数据转换层 3.客户端框架之代理层 框架结构 框架是基于C#的,在V ...
- 基于Web Service的客户端框架搭建二:数据转换层(FCL)
引言 要使用WebService来分离客户端与服务端,必定要使用约定好两者之间的数据契约.Json数据以其完全独立于语言的优势,成为开发者的首选.C# JavaScriptSerializer为Jso ...
- 基于Web Service的客户端框架搭建一:C#使用Http Post方式传递Json数据字符串调用Web Service
引言 前段时间一直在做一个ERP系统,随着系统功能的完善,客户端(CS模式)变得越来越臃肿.现在想将业务逻辑层以下部分和界面层分离,使用Web Service来做.由于C#中通过直接添加引用的方来调用 ...
- 基于JavaScript的REST客户端框架
现在REST是一个比较热门的概念,REST已经成为一个在Web上越来越常用的应用,基于REST的Web服务越来越多,包括Twitter在内的微博客都是用REST做为对外的API,先前我曾经介绍过“基于 ...
- 《基于 Web Service 的学分制教务管理系统的研究与实现》论文笔记(十一)
标题:基于 Web Service 的学分制教务管理系统的研究与实现 一.基本内容 时间:2014 来源:苏州大学 关键词:: 教务管理系统 学分制 Web Service 二.研究内容 1.教务管理 ...
- 基于Docker的TensorFlow机器学习框架搭建和实例源码解读
概述:基于Docker的TensorFlow机器学习框架搭建和实例源码解读,TensorFlow作为最火热的机器学习框架之一,Docker是的容器,可以很好的结合起来,为机器学习或者科研人员提供便捷的 ...
- MyEclipse构建Web Service(Xfire框架)
以下是本人原创,如若转载和使用请注明转载地址.本博客信息切勿用于商业,可以个人使用,若喜欢我的博客,请关注我,谢谢!博客地址 任务要求: 使用Xfire实现一个简单的CalculatorWebServ ...
- JAVA开发Web Service几种框架介绍
郑重声明:此文为转载来的,出处已不知了,侵告删. 在讲Web Service开发服务时,需要介绍一个目前开发Web Service的几个框架,分别为Axis,axis2,Xfire,CXF以及JWS( ...
- SOAP: java+xfire(web service) + php客户端
作者: 吴俊杰 web service这项技术暂不说它有多落伍,但是项目中用到了,没法逃避! xml和json各有各的好处,但是JSON无疑是当今数据交互的主流了.客户soap服务器端用的是 j ...
随机推荐
- 解决UITableView上的cell的重用
1.通过为每个cell指定不同的重用标识符(reuseIdentifier)来解决 // static NSString *rankCellIndefier = @"rankC ...
- c语言:辗转相除法求最大公约数、最小公倍数
辗转相除法,又称欧几里得算法.两个正整数a和b(a>b),它们的最大公约数等于余数c和较小的数b之间的最大公约数.最小公倍数=两数之积/最大公约数 #include <stdio.h> ...
- CentOS 6 安装Redmine
Redmine是一个灵活的项目管理web应用,采用Ruby on Rails框架开发.Redmine是典型的web 2.0网站,项目管理系统的后起之秀.Redmine支持多项目,灵活的角色权限管理,灵 ...
- Codeforces Round #265 (Div. 2) E. Substitutes in Number
http://codeforces.com/contest/465/problem/E 给定一个字符串,以及n个变换操作,将一个数字变成一个字符串,可能为空串,然后最后将字符串当成一个数,取模1e9+ ...
- C# 函数式编程及Monads.net库
函数式编程中,一切皆为函数,这个函数一般不是类级别的,其可以保存在变量中,可以当做参数或返回值,是函数级别的抽象和重用,将函数作为可重用的基本模块,就像面向对象中一切皆为对象,把所有事物抽象为类,面向 ...
- 所有网卡常用信息获取集中展示(CentOS6 &CentOS7)
查看所有网卡,状态.光电类型.ip.广播地址.掩码 1.命令如下 ( string='|%-3s|%-18s|%-10s|%-10s|%-10s|%-16s|%-16s|%-16s|'; br=&qu ...
- jQuery WeUI V0.4.2 发布
http://www.oschina.net/news/71590/jquery-weui-v0-4-2 jQuery WeUI V0.4.2 发布了! jQuery WeUI 中使用的是官方WeUI ...
- 一致性hash(整理版)
简单解释: 简单解释一致性hash的原理:网上通篇都是用服务器做的举例,我这里也如此,主要是便于理解. 通常:有N个客户端请求服务器,假设有M台web服务器,通常为了均衡访问会进行N%M的取模,然后分 ...
- RouteOS 频繁自启
本来是一个美好的大周末,突然却被一个突如其来的电话把我从美梦中惊醒,然而一切还不止这么简单...... 本来刚开始了解到信息是客户的一台RouteOS设备挂了,听到这个消息时觉得自己应该可以很 ...
- jquery基于form-data文件上传
1.html代码 <input type="file" name="myupdate" id="myupdate"> 2.jav ...