本文主要介绍了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.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监听服务并无区别。
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服务的.Net库,那么就使用HttpListener监听http请求自行解出其中的输入数据,再根据SOAP协议进行处理。以此方式实现WebService服务。
到此这篇关于C#中C/S端实现WebService服务的文章就介绍到这了,更多相关C# C/S端 WebService 内容请搜索得得之家以前的文章希望大家以后多多支持得得之家!
本文标题为:C#中C/S端实现WebService服务
基础教程推荐
- C#类和结构详解 2023-05-30
- linux – 如何在Debian Jessie中安装dotnet core sdk 2023-09-26
- C#控制台实现飞行棋小游戏 2023-04-22
- unity实现动态排行榜 2023-04-27
- winform把Office转成PDF文件 2023-06-14
- C# List实现行转列的通用方案 2022-11-02
- C# windows语音识别与朗读实例 2023-04-27
- 一个读写csv文件的C#类 2022-11-06
- ZooKeeper的安装及部署教程 2023-01-22
- C# 调用WebService的方法 2023-03-09