<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
使用 C#以B/S方式構建WebService服務十分簡便,即是使用Asp.net在網站中新增WebService服務並使用IIS釋出。但如需要在C/S程式中釋出WebService服務則沒有直接可用的類庫。因此需要使用另外的方式實現WebService服務。
WebService實際是使用Http並遵循SOAP協定格式進行互動。能夠進行Http通訊即可實現WebService服務,只是沒了現成的類庫就需要自己編寫解析SOAP格式封包和組織應答包。
程式碼如下(範例):
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using System.Net; using System.Web; namespace LadarManufacturabilityTooling { public class HttpServic { public delegate byte[] OnGetResponseDataHandle(HttpListenerPostValue Sender); public event OnGetResponseDataHandle OnGetResponse; private static HttpListener httpPostRequest = new HttpListener(); private static bool IsRun = true; public HttpServic(IPAddress HttpServerIP, int HttpServerPort) { httpPostRequest.Prefixes.Add("http://" + HttpServerIP.ToString() + ":" + HttpServerPort.ToString() + "/"); try { httpPostRequest.Start(); } catch(Exception ex) { string Mes = ex.Message; } Thread ThrednHttpPostRequest = new Thread(new ThreadStart(httpPostRequestHandle)); ThrednHttpPostRequest.Start(); } private void httpPostRequestHandle() { while (IsRun) { try { HttpListenerContext requestContext = httpPostRequest.GetContext(); Thread threadsub = new Thread(new ParameterizedThreadStart((requestcontext) => { HttpListenerContext request = (HttpListenerContext)requestcontext; //獲取Post請求中的引數和值幫助類 HttpListenerPostParaHelper httppost = new HttpListenerPostParaHelper(request); //獲取Post過來的引數和資料 HttpListenerPostValue lst = httppost.GetHttpListenerPostValue(); byte[] buffer = null; if (lst != null) { if(OnGetResponse != null) buffer = OnGetResponse(lst); } if(buffer != null) {//Response try { request.Response.StatusCode = 200; request.Response.Headers.Add("SOAPAction", ""); request.Response.Headers.Add("User-Agent", "gSOAP/2.8"); request.Response.ContentType = "text/xml; charset=utf-8"; request.Response.ContentEncoding = Encoding.UTF8; request.Response.ContentLength64 = buffer.Length; var output = request.Response.OutputStream; output.Write(buffer, 0, buffer.Length); output.Close(); } catch(Exception ex2) { } } else { try { request.Response.Close(); } catch { } } })); threadsub.Start(requestContext); } catch (Exception ex) { string Mes = ex.Message; } } } public void StopHttpThread() { IsRun = false; httpPostRequest.Abort(); } } }
啟動服務後在httpPostRequestHandle()函數中編寫對監聽到的服務請求的處理。
//獲取Post過來的引數和資料 HttpListenerPostValue lst = httppost.GetHttpListenerPostValue();
GetHttpListenerPostValue();函數作用為取出請求中的資料部分和請求的名稱。涉及到的類定義和程式碼如下:
/// <summary> /// HttpListenner監聽Post請求引數值實體 /// </summary> public class HttpListenerPostValue { /// <summary> /// 0=> 引數 /// 1=> 檔案 /// </summary> public int type = 0; /// <summary> /// 請求的型別名稱 /// </summary> public string name; /// <summary> /// 資料字串 /// </summary> public string datas; }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Web; using System.IO; namespace LadarManufacturabilityTooling { /// <summary> /// 獲取Post請求中的引數和值幫助類 /// </summary> public class HttpListenerPostParaHelper { private HttpListenerContext request; public HttpListenerPostParaHelper(HttpListenerContext request) { this.request = request; } /// <summary> /// 獲取Post過來的引數和資料 /// </summary> /// <returns></returns> public HttpListenerPostValue GetHttpListenerPostValue() { try { HttpListenerPostValue HttpListenerPostValueList = new HttpListenerPostValue(); if (true) { Stream body = request.Request.InputStream; Encoding encoding = Encoding.UTF8; StreamReader reader = new System.IO.StreamReader(body, encoding); if (request.Request.ContentType != null) { Console.WriteLine("Client data content type {0}", request.Request.ContentType); } string datas = reader.ReadToEnd(); string Requestname = request.Request.RawUrl.Replace("/",""); HttpListenerPostValueList.datas = datas; HttpListenerPostValueList.name = Requestname; Console.WriteLine(datas); } return HttpListenerPostValueList; } catch (Exception ex) { return null; } } } }
以上部分和構建普通的http監聽服務並無區別。
OnGetResponse事件用於處理請求的資料並組織回包
程式碼如下(範例):
private byte[] ThisHttpServic_OnGetResponse(HttpListenerPostValue Sender) { byte[] buffer = null; string restr = ""; //處理收到的請求 switch (Sender.name) { case "MyServiceName": { string xmlOrgstr = ""; int iStartPos = Sender.datas.IndexOf("<xmlData>", 1); int iStopPos = Sender.datas.IndexOf("</xmlData>", 1); if (iStartPos > 0) { xmlOrgstr = Sender.datas.Substring(iStartPos + 9, iStopPos - iStartPos - 9); } string xmlstr = HttpUtility.HtmlDecode(xmlOrgstr); string LOGIN_ACK = GetPack(xmlstr); restr = GetCompleteSoapString(System.Security.SecurityElement.Escape(LOGIN_ACK)); break; } default: restr = ""; break; } buffer = System.Text.Encoding.UTF8.GetBytes(restr); return buffer; }
需要從收到的http請求的資料部分提取出WebService服務的引數。
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:client1="http://LSCService.chinamobile.com" xmlns:service1="http://FSUService.chinamobile.com"> <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <client1:invoke> <xmlData><?xml version="1.0" encoding="UTF-8" ?><Request><PK_Type><Name>LOGIN</Name></PK_Type><Info><UserName>cmcc</UserName><PassWord>B101341CC2E4D6F5B395C7544B96A826</PassWord><FSUID>21202110060001</FSUID><FSUIP>192.168.1.253</FSUIP><FSUMAC>00:21:92:01:b5:9f</FSUMAC><FSUVER>2.0.0.15 for CMCC</FSUVER></Info></Request>
 </xmlData> </client1:invoke>< /SOAP-ENV:Body> </SOAP-ENV:Envelope>
收到的封包原文(Sender.datas)為:
作為範例的服務的引數名為xmlData從SOAP中擷取出引數的字串進行處理。
由於xmlData中的內容是一串xml字元,SOAP傳輸時經過了跳脫,因此還需要跳脫回來。
string xmlstr = HttpUtility.HtmlDecode(xmlOrgstr);
處理完相應的業務,將需要回復的資料加上SOAP協定的頭尾組好回覆包返回。需要跳脫的部分記得進行符號跳脫。
System.Security.SecurityElement.Escape(LOGIN_ACK)
SOAP協定的頭尾根據WebService服務函數的定義有所不同,需要自行組織。範例如下:
/// <summary> /// 返回完整的SOAP包 /// </summary> /// <param name="XmlData">應答部分</param> /// <returns></returns> public static string GetCompleteSoapString(string XmlData) { string restr = "<?xml version="1.0" encoding="UTF-8"?>" + "<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"" + " xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"" + " xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"" + " xmlns:xsd="http://www.w3.org/2001/XMLSchema"" + " xmlns:client1="http://LService.mobile.com"" + " xmlns:service1="http://FService.mobile.com">" + "<SOAP-ENV:Body>" + "<client1:invokeResponse><invokeReturn>"; string restrEnd = "</invokeReturn></client1:invokeResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>"; restr = restr + XmlData + restrEnd; return restr; }
既然C# 並未提供在C/S程式使用的WebService服務的.Net庫,那麼就使用HttpListener監聽http請求自行解出其中的輸入資料,再根據SOAP協定進行處理。以此方式實現WebService服務。
到此這篇關於C#中C/S端實現WebService服務的文章就介紹到這了,更多相關C# C/S端 WebService 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45