我们开发winform程序时,通常使用传统的三层结构,包括:数据层、业务层、页面层。Form页面调用时,直接new个Service类,实现业务需求。但这种模式有个弊端,就是业务逻辑全部放到了客户端。这样操作对客户端的机器要求很高,又很容易被攻击或源码泄露。因此,越来越多的winform项目,也通过webapi接口实现业务逻辑。
1、定义webapi接口
我们先定义好两个webapi接口,一个get访问、另一个post访问。在vs中创建webapi的教程请参考这篇博客。开发、调试和部署完成后。我们就可以写winform端的代码了。
https://webapi2.navisoft.com.cn/api/DatumApi/TestHttpGet
https://webapi2.navisoft.com.cn/api/DatumApi/TestHttpPost
2、实现get访问
我们使用WebClient这个对象即可
2.1、调用代码如下
//get访问 string urlPath = @"https://webapi2.navisoft.com.cn/api/DatumApi/TestHttpGet?queryParams=hello-vincent.q"; string modelRes = UrlHelper.WebMethodGetData(urlPath);
2.2、返回结果
{"code":"0","msg":"访问成功,时间:2022-09-24 17:38:23","msgEx":null,"stackTrace":null,"actionName":null,"content":"Query参数hello-vincent.q","apiinfoJson":null}
3、实现post访问
这个代码有些复杂,因为要定义的参数的传输格式,就是如何接收和获取?推荐使用application/json和application/x-www-form-urlencoded这两种格式。
3.1、调用代码如下
DatumOpenApiQueryModel modelP = new DatumOpenApiQueryModel() { openId = "id1", nickName = "name1", text = "text1", param1 = "param1", actionName = "action1" }; string jsonP = JsonHelper.GetJsonByObject(modelP); string urlPath = @"https://webapi2.navisoft.com.cn/api/DatumApi/TestHttpPost"; string modelRes = UrlHelper.WebMethodPostData(urlPath, jsonP, "utf-8", "application/json");
3.2、返回结果
{"code":"0","msg":"访问成功,时间:2022-09-24 17:12:43","msgEx":null,"stackTrace":null,"actionName":null,"content":"Form参数{\"openId\":\"id1\",\"nickName\":\"name1\",\"actionName\":\"action1\",\"text\":\"text1\",\"param1\":\"param1\",\"openPlat\":null,\"imageBase64\":null,\"imageBase64_2\":null,\"audioBase64\":null,\"fileBase64\":null,\"fileName\":null,\"productKind\":null,\"queryName\":null,\"quickSearch\":null,\"productName\":null,\"accessToken\":null,\"accessProductCode\":null,\"accessProductVersion\":null,\"wxUserCode\":null,\"wxAccessToken\":null,\"currentUserCode\":null,\"currentUserName\":null,\"logonType\":0,\"recordCount\":0,\"pageInfo\":null,\"orderBys\":{}}","apiinfoJson":null}
4、如何实现?
如何实现get和post访问的代码如下所示,也不是很复杂吧?
/// <summary> /// 提交GET方法至指定的Url,解析返回的数据 /// </summary> /// <param name="url"></param> /// <param name="charset"></param> /// <returns></returns> [ShortDescription("根据Get方式请求URL下载数据")] public static string WebMethodGetData(string url, string charset = "utf-8") { WebResponse response = null; Stream receiveStream = null; try { WebClientEx wc = new WebClientEx(); byte[] byteResponse = wc.DownloadData(url); wc.Dispose(); //及时释放、避免第二次下载时、奇怪的"操作超时"的问题 //字符集为UTF8 string responseStr = Encoding.GetEncoding(charset).GetString(byteResponse); return responseStr; } catch (WebException ex) { string errorMessage = ex.Message; //需判断response是否==null response = ex.Response; if (response == null) { dynamic objErrorData = new { message = errorMessage, subErrors = "" }; string jsonErrorData = JsonHelper.GetJsonByObject(objErrorData); throw new CustomApiJsonException(jsonErrorData, url, ex); } else { receiveStream = response.GetResponseStream(); Encoding encode = Encoding.GetEncoding(charset); StreamReader sr = new StreamReader(receiveStream, encode); char[] readbuffer = new char[2048]; int n = sr.Read(readbuffer, 0, 2048); string result = string.Empty; while (n > 0) { string str = new string(readbuffer, 0, n); result += str; n = sr.Read(readbuffer, 0, 2048); } response.Close(); //此处将错误信息和json信息同时返回 dynamic objErrorData = new { message = errorMessage, subErrors = result }; string jsonErrorData = JsonHelper.GetJsonByObject(objErrorData); throw new CustomApiJsonException(jsonErrorData, url, ex); } } finally { //使用完后、释放资源 if (response != null) response.Close(); if (receiveStream != null) receiveStream.Close(); } } /// <summary> /// 提交POST方法至指定的Url,解析返回的数据 /// 参考地址:http://www.cnblogs.com/teikey/p/3373882.html /// </summary> /// <param name="url"></param> /// <param name="requestParam"></param> /// <param name="charset"></param> /// <param name="contentType"></param> /// <param name="dicHeader"></param> /// <returns></returns> [ShortDescription("根据Post方式请求URL下载数据")] public static string WebMethodPostData(string url, string requestParam, string charset = "utf-8", string contentType = "application/x-www-form-urlencoded",Dictionary<string,string>dicHeader=null) { WebRequest hr = null; WebResponse response = null; Stream receiveStreamIn = null; Stream receiveStreamOut = null; StreamReader srIn = null; StreamReader srOut = null; try { //创建访问对象 hr = HttpWebRequest.Create(url); hr.Timeout = requestTimeOut; //拼接参数 byte[] buf = System.Text.Encoding.GetEncoding(charset).GetBytes(requestParam); //hr.ContentType = "application/x-www-form-urlencoded"; hr.ContentType = contentType; hr.ContentLength = buf.Length; hr.Method = "POST"; if (dicHeader != null) { foreach (string sKey in dicHeader.Keys) { string sValue = dicHeader[sKey]; hr.Headers.Add(sKey, sValue); } } System.IO.Stream RequestStream = hr.GetRequestStream(); RequestStream.Write(buf, 0, buf.Length); RequestStream.Close(); response = hr.GetResponse(); receiveStreamIn = response.GetResponseStream(); Encoding encode = Encoding.GetEncoding(charset); srIn = new StreamReader(receiveStreamIn, encode); char[] readbuffer = new char[2048]; int n = srIn.Read(readbuffer, 0, 2048); string result = string.Empty; while (n > 0) { string str = new string(readbuffer, 0, n); result += str; n = srIn.Read(readbuffer, 0, 2048); } response.Close(); //注:此处用完以后立即关闭 //如果未取得Json数据,则抛出异常 if (string.IsNullOrEmpty(result)) throw new CustomApiException("消息长度:" + response.ContentLength + "消息内容:" + response.ToString(), url); return result; } catch (WebException ex) { string errorMessage = ex.Message; //需判断response是否==null response = ex.Response; if (response == null) { dynamic objErrorData = new { message = errorMessage, subErrors = "" }; string jsonErrorData = JsonHelper.GetJsonByObject(objErrorData); throw new CustomApiJsonException(jsonErrorData, url + "?" + requestParam, ex); } else { receiveStreamOut = response.GetResponseStream(); Encoding encode = Encoding.GetEncoding(charset); srOut = new StreamReader(receiveStreamOut, encode); char[] readbuffer = new char[2048]; int n = srOut.Read(readbuffer, 0, 2048); string result = string.Empty; while (n > 0) { string str = new string(readbuffer, 0, n); result += str; n = srOut.Read(readbuffer, 0, 2048); } response.Close(); //此处将错误信息和json信息同时返回 dynamic objErrorData = new { message = errorMessage, subErrors = result }; string jsonErrorData = JsonHelper.GetJsonByObject(objErrorData); throw new CustomApiJsonException(jsonErrorData, url + "?" + requestParam, ex); } } finally { //http://www.cnblogs.com/huangtailang/archive/2013/07/09/3180651.html if (hr != null) hr.Abort();//中止请求 hr = null; //需要写下Null if (response != null) response.Close(); if (receiveStreamIn != null) receiveStreamIn.Close(); if (receiveStreamOut != null) receiveStreamOut.Close(); if (srIn != null) srIn.Close(); if (srOut != null) srOut.Close(); System.GC.Collect();//强制垃圾回收,并释放资源 } } /// <summary> /// 生成图片流的字符串参数值(目前用于速卖通图片上传) /// </summary> /// <param name="url"></param> /// <param name="stream"></param> /// <param name="contentType"></param> /// <returns></returns> [ShortDescription("根据Post方式请求URL下载数据")] public static string WebMethodPostData(string url, Stream stream, string contentType) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Timeout = requestTimeOut; try { request.Method = "POST"; request.Accept = "*/*"; request.KeepAlive = true; request.ContentType = contentType; request.Credentials = System.Net.CredentialCache.DefaultCredentials; request.ContentLength = stream.Length; using (Stream requestStream = request.GetRequestStream()) { //将内存流数据读取位置归零 stream.Position = 0; byte[] tempBuffer = new byte[stream.Length]; stream.Read(tempBuffer, 0, tempBuffer.Length); stream.Close(); //将内存流中的buffer写入到请求写入流 requestStream.Write(tempBuffer, 0, tempBuffer.Length); requestStream.Close(); //获取到上传请求的响应 WebResponse response = request.GetResponse(); //获取到上传返回的数据 StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8); string content = reader.ReadToEnd(); response.Close(); request = null; return content; } } finally { if (request != null) request.Abort();//中止请求 request = null; //需要写下Null System.GC.Collect();//强制垃圾回收,并释放资源 } }
public class WebClientEx : WebClient { private int timeOut = 200; //自定义读写超时设置(s) protected override WebRequest GetWebRequest(Uri address) { WebRequest request = base.GetWebRequest(address); request.Timeout = timeOut * 1000; return request; } }
想要完整代码的小伙伴,可加小编微信:xiyang1011,免费领取
221102补充
1、JsonHelper.GetJsonByObject(objErrorData),这个方法是引用Newtonsoft.Json这个类库,将Mode类转为Json的,一句代码就能搞定
2、CustomApiJsonException,这个类是基于Exception的创建的,直接改成这个就可以
3、所有代码加起来,其实就是完整的代码。哪里不清楚的,再加小编微信
文章评论