当前位置:网站首页>C#中C/S端如何实现WebService服务
C#中C/S端如何实现WebService服务
2022-07-22 21:52:00 【亿速云】
C#中C/S端如何实现WebService服务
本篇内容介绍了“C#中C/S端如何实现WebService服务”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
前言
使用 C#以B/S方式构建WebService服务十分简便,即是使用Asp.net在网站中添加WebService服务并使用IIS发布。但如需要在C/S程序中发布WebService服务则没有直接可用的类库。因此需要使用另外的方式实现WebService服务。
一、实现思路
WebService实际是使用Http并遵循SOAP协议格式进行交互。能够进行Http通讯即可实现WebService服务,只是没了现成的类库就需要自己编写解析SOAP格式数据包和组织应答包。
二、步骤
1.使用HttpListener构建服务
代码如下(示例):
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.ContentLength74 = 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监听服务并无区别。
2.处理请求的数据
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服务”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
边栏推荐
- 初出茅庐的小李第108篇博客二进制打印
- Mysql A left(right) join B on A.id=B. ID and a.age=1 and a left (right) join b on a.id=b id where A.age=1
- 程序员最想干的三件事 |漫画
- Experiment 4 DPCM
- Topic domain model
- yolov5 test.py BrokenPipeError: [Errno 32] Broken pipe问题解决
- 实验四 DPCM
- Three effective strategies for driving page performance optimization
- 数据库基础及安装
- 自定义flink es source
猜你喜欢

zabbix agent创建监控项

6-13漏洞利用-smtp暴力破解

LeetCode(剑指 Offer)- 11. 旋转数组的最小数字

使用路由协议配置 IPv6 over IP手动隧道

scala idea提示函数参数

VMware virtual machine changes static IP and reports an error unit network Service entered failed state solution

Worthington溶菌酶技术说明及文献参考

【开发技术】SpingBoot数据库与持久化技术,JPA,MongoDB,Redis

PNY file to picture

我在京东使用工厂模式,一文说清楚工厂模式
随机推荐
Experiment 2 YUV
Kubernetes deployment strategy
如何配置CANoe Network-based access模式的以太网网络拓扑
初出茅庐的小李第110篇博客之详细剖析STM32中__NVIC_SetPriorityGrouping(uint32_t PriorityGroup)函数
MySQL消息队列表结构
LAN SDN hard core technology insider 19 unite all forces that can be united
ASP. Net core creates MVC projects and uploads multiple files (streaming)
Expérience II Yuv
Simulate not all endpoints registered exceptions and Solutions
Qt文档阅读笔记-QAudioInput&QAudioFormat解析与实例
etcdv3·watch操作实现及相关重点说明
Scala learning -- six uses of generics [t]
亚马逊旗下Zoox通过安全测试 并在加州申请试驾
Scala Generic 泛型类详解 - T
驱动页面性能优化的3个有效策略
Amazon's zoox passed the safety test and applied for a test drive in California
Fastapi learning (II) -- fastapi+jinjia2 template rendering web page (jump back to the rendering page)
Experiment 5 JPEG
實驗二 YUV
组蛋白研究丨Worthington小牛胸腺组蛋白的特征及文献参考