C#中C/S端实现WebService服务

目录
  • 前言
  • 一、实现思路
  • 二、步骤
    • 1.使用HttpListener构建服务
    • 2.处理请求的数据
  • 总结

前言

使用 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>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;&lt;Request&gt;&lt;PK_Type&gt;&lt;Name&gt;LOGIN&lt;/Name&gt;&lt;/PK_Type&gt;&lt;Info&gt;&lt;UserName&gt;cmcc&lt;/UserName&gt;&lt;PassWord&gt;B101341CC2E4D6F5B395C7544B96A826&lt;/PassWord&gt;&lt;FSUID&gt;21202110060001&lt;/FSUID&gt;&lt;FSUIP&gt;192.168.1.253&lt;/FSUIP&gt;&lt;FSUMAC&gt;00:21:92:01:b5:9f&lt;/FSUMAC&gt;&lt;FSUVER&gt;2.0.0.15 for CMCC&lt;/FSUVER&gt;&lt;/Info&gt;&lt;/Request&gt;


</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 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C# 调用 JavaWebservice服务遇到的问题汇总

    1. A SOAP 1.2 message is not valid when sent to a SOAP 1.1 only endpoint. 问题原因: 客户端和服务端的SOAP协议版本不一致. 解决方法: ①修改客户端SOAP协议版本和服务端一致 ②修改服务端SOAP协议版本和客户端一致 附Java服务端修改服务暴露SOAP版本方法: 在接口的实现类上面添加注解 //import javax.xml.ws.BindingType; //import javax.xml.ws.soap.S

  • .NET C#创建WebService服务简单实例

    Web service是一个基于可编程的web的应用程序,用于开发分布式的互操作的应用程序,也是一种web服务 WebService的特性有以下几点: 1.使用XML(标准通用标记语言)来作为数据交互的格式. 2.跨平台性,因为使用XML所以只要本地应用可以连接网络解析XML就可以实现数据交换,比如安卓.IOS.WindowsPhone等都可以实现对Web service的数据交互. 3.基于HTTP协议,直接跨越防火墙,通用型强: 下面使用Visual Studio 2013(其他VS版本亦是

  • c#编写webservice服务引用实例分享

    首先在新建了一个web服务文件. 复制代码 代码如下: public  SqlWhhWebService1()        {            InitializeComponent();        }        #region Component Designer generated code //Required by the Web Services Designer         private IContainer components = null; /// <su

  • C#中C/S端实现WebService服务

    目录 前言 一.实现思路 二.步骤 1.使用HttpListener构建服务 2.处理请求的数据 总结 前言 使用 C#以B/S方式构建WebService服务十分简便,即是使用Asp.net在网站中添加WebService服务并使用IIS发布.但如需要在C/S程序中发布WebService服务则没有直接可用的类库.因此需要使用另外的方式实现WebService服务. 一.实现思路 WebService实际是使用Http并遵循SOAP协议格式进行交互.能够进行Http通讯即可实现WebServi

  • java如何实现post请求webservice服务端

    目录 post请求webservice服务端 1.例如我此时有一个wsdl文件 2.点击row查看具体的发送参数 3.代码实现 3.1参数说明 用post请求调用webservice post请求webservice服务端 当生成webService的客户端不好实现时,通过java的post请求不失为一种好办法. 1.例如我此时有一个wsdl文件 http://xxx.xxx.xxx.xxx:8081/APIService.svc?wsdl 2.通过SoapUI 我们可以将swdl文件转换.从而

  • Spring Boot 实现Restful webservice服务端示例代码

    1.Spring Boot configurations application.yml spring: profiles: active: dev mvc: favicon: enabled: false datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/wit_neptune?createDatabaseIfNotExist=true&useUnicode=true&

  • PHP中soap用法示例【SoapServer服务端与SoapClient客户端编写】

    本文实例讲述了PHP中soap用法.分享给大家供大家参考,具体如下: 一.首先要设置服务器环境 修改php.ini 得添加extension=php_soap.dll (加载soap 内置包) 修改soap.wsdl_cache_enabled=1 改为soap.wsdl_cache_enabled=0 这个是soap的缓存,测试的时候最好改为0,上线稳定了改为1 soap有两种模式一种是wsdl,一种是no-wsdl 二.熟悉几个函数 1. SoapServer SoapServer用于创建p

  • 基于JAVA中使用Axis发布/调用Webservice的方法详解

    本示例和参考文章的差别在于: 1)deploy.wsdd定义的更详细(对于server端定义了接口:ICalculate): 复制代码 代码如下: <deployment xmlns="http://xml.apache.org/axis/wsdd/"    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">    <service name="Calculate&qu

  • java调用WebService服务的四种方法总结

    目录 一.前言 二.简介   三.具体解析 第一种方式,首先得下载axis2的jar包,Axis2提供了一个wsdl2java.bat命令可以根据WSDL文件自动产生调用WebService的代码. 第二种RPC 方式,强烈推荐. 第三种:利用HttpURLConnection拼接和解析报文进行调用. 第四种,利用httpclient 总结 一.前言 本来不想写这个的,因为网上类似的是在是太多了.但是想想自己前面段时间用过,而且以后可能再也没机会用了.所以还是记录一下吧.我这儿是以C语言生成的W

  • SpringBoot整合WebService服务的实现代码

    目录 为什么使用WebService? 适用场景: 不适用场景: Axis2与CXF的区别 SpringBoot使用CXF集成WebService WebService是一个SOA(面向服务的编程)的架构,它是不依赖于语言,不依赖于平台,可以实现不同的语言间的相互调用,通过Internet进行基于Http协议的网络应用间的交互. 其实WebService并不是什么神秘的东西,它就是一个可以远程调用的类,或者说是组件,把你本地的功能开放出去共别人调用. 为什么使用WebService? 简单解释一

  • ASP.NET调用WebService服务的方法详解

    本文实例讲述了ASP.NET调用WebService服务的方法.分享给大家供大家参考,具体如下: 一.WebService:WebService是以独立于平台的方式,通过标准的Web协议,可以由程序访问的应用程序逻辑单元. (1)应用程序逻辑单元:web服务包括一些应用程序逻辑单元或者代码.这些代码可以完成运算任务,可以完成数据库查询,可以完成计算机程序能够完成的任何工作. (2)可由程序访问:当前大多是web站点都是通过浏览器由人工访问的,web服务可以由计算机程序来访问. (3)标准的we协

  • 在PHP中利用wsdl创建标准webservice的实现代码

    1.创建wsdl 说明: A.非标准的webservice,可能只能PHP才能访问 B.标准的webservice,就必须要使用wsdl(webservice description language,就是用XML语法标准来描述你的服务内容,我是这么理解的) 在这里我只介绍标准的webservice. 那么如何创建wsdl呢?对于PHP来说这确实是件很不容易的事情,有人说用zend studio创建很方便,这是一种方法.但对于那些不喜欢用zend studio的人来说,会觉得创建一个webser

随机推荐