基于Web Service的客户端框架搭建三:代理层(Proxy)
2014-08-15 09:17
405 查看
前言
代理层的主要工作是调用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, 0, 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的客户端框架搭建二:数据转换层(FCL)
- 基于Web Service的客户端框架搭建一:C#使用Http Post方式传递Json数据字符串调用Web Service
- 基于Web Service的客户端框架搭建四:终结篇
- 基于Web Service的客户端框架搭建一:C#使用Http Post方式传递Json数据字符串调用Web Service
- 基于Web Service的客户端框架搭建一:C#使用Http Post方式传递Json数据字符串调用Web Service
- 基于Web Service的客户端框架搭建一:C#使用Http Post方式传递Json数据字符串调用Web Service
- 基于mirrorrr搭建的自己的在线代理(http://zfqproxy.appspot.com/)
- IOS开发-基于WebDriverAgent代理服务,实现iOS手机app自动化测试的框架搭建
- 基于 SailingEase WinForm Framework 开发优秀的客户端应用程序(2:开始搭建模块化的程序框架)
- 异步消息总线hornetq学习-01基于maven的客户端程序框架搭建
- 客户端自动化测试之Proxy框架介绍
- 基于即时通信和LBS技术的位置感知服务(三):搭建Openfire服务器+测试2款IM客户端
- 实战搭建Gearman 分布式处理框架 + python客户端
- 基于CAS搭建JavaEE单点登录框架(客户端)(取消https证书验证)
- 基于移动平台的多媒体框架——用VLC搭建简单的流媒体服务器
- 采用CakePHP框架为Android应用快速搭建Web Service服务器及API接口的PHP代码实例
- 基于Linux搭建一个类似Qik手机录像直播平台(服务器端:feng streaming server + web server,客户端:Android手机应用)
- SilverLight企业应用框架设计【四】实体层设计+为客户端动态生成服务代理(自己实现RiaService)
- 基于MFC的OPENGL绘图框架搭建
- 如何使用apache mod_proxy和Tomcat搭建基于SSL的loadbalance集群环境