欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#调用和实现WebService,纯手工打造!

程序员文章站 2023-11-27 09:12:52
先为啥要纯手工打造呢,因为对方是用c++做的,我按照他们给出的wsdl实现了一个webservice,结果他们完全不能调用。具体是他们调用的问题还是wsdl定义的问题,不可...

先为啥要纯手工打造呢,因为对方是用c++做的,我按照他们给出的wsdl实现了一个webservice,结果他们完全不能调用。具体是他们调用的问题还是wsdl定义的问题,不可考了。

悲催的弱势方……只能我们去配合他们。不提了。

 

首先用c#调用对方的webservice。
因为对方用的c++实现,添加web服务引用方式无效……直接添加wsdl的调用对方不认……

只好手工打造,还好c#足够强大。

httpwebrequest类可以简单的实现webservice调用。

 

首先手工打造soap包内容

复制代码 代码如下:

string soap =
    "<soapenv:envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:down=\"http://down.wsdl.position.mdd.ailk.com\" xmlns:in=\"http://in.object.down.wsdl.position.mdd.ailk.com\">"
    + "<soapenv:header/>"
    + "<soapenv:body>"
    + "<testfunc>"
        + "<object>test message</object>"
    + "</testfunc>"
    + "</soapenv:body>"
    + "</soapenv:envelope>";



构造httpwebrequest对象

复制代码 代码如下:

httpwebrequest request = (httpwebrequest)httpwebrequest.create("http://localhost:8088/");
request.method = "post";
request.contenttype = "text/xml; charset=utf-8";
request.headers.add("soapaction", "/testfunc");
byte[] bts = encoding.utf8.getbytes(soap);


发送请求

复制代码 代码如下:

request.contentlength = data.length;
stream writer = request.getrequeststream();
writer.write(data, 0, data.length);
writer.close();


获取返回信息

复制代码 代码如下:

streamreader sr = new streamreader(request.getresponse().getresponsestream(), encoding.utf8);
string retxml = sr.readtoend();
sr.close();

之后按照wsdl的定义,解析返回的xml串就好了。

当然手工打造就是累……

如果是标准的webservice,直接一句string str = serv.testfunc(“”);

不提了。

c#实现webservice给对方调用
按照我的理解,webservice底层是soap,本质上就是一个tcp的短连接。

解决的思路就是用c#来实现一个tcp的服务端,然后手工分析请求内容。

复制代码 代码如下:

//开始监听端口
mylistener = new tcplistener(ipaddress.parse(listenipaddr), listenport);
mylistener.start();


接收连接,并且获取请求内容
复制代码 代码如下:

//接受新连接
socket mysocket = mylistener.acceptsocket();
string sbuffer = "";
byte[] breceive = new byte[2048];

// 接收请求内容
int i = mysocket.receive(breceive, breceive.length, 0);
sbuffer = encoding.ascii.getstring(breceive);

// 只处理 "post"请求类型
if (sbuffer.substring(0, 4) != "post")
{
    return;
}


截取soap:body部分
复制代码 代码如下:

string soap = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
int istartpos = sbuffer.indexof("<soap:body>", 1);
int istoppos = sbuffer.indexof("</soap:body>", 1);

if (istartpos > 0)
{
    soap = soap + sbuffer.substring(istartpos, istoppos - istartpos + 9);
}



分析请求内容这里就略了。

返回消息的构造如下。

首先构造消息体内容

复制代码 代码如下:

string ret = string.format(
            ""
            + "<soapenv:envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:down=\"http://down.wsdl.position.mdd.ailk.com\" xmlns:out=\"http://out.object.down.wsdl.position.mdd.ailk.com\">\n"
            + "<soapenv:header/>\n"
            + "<soapenv:body>\n"
            + "<testrsp>\n"
            + "<object resultcode=\"0\"/>\n"
            + "</testrsp>\n"
            + "</soapenv:body>\n"
            + "</soapenv:envelope>"
            );
byte[] bytes = encoding.ascii.getbytes(ret);



构造消息头部

复制代码 代码如下:

// 构造头部
string smimetype = "text/html";
string shttpversion = "http/1.1 ";
string sbuffer = "";

if (smimeheader.length == 0)
{
    smimeheader = "text/html"; // 默认 text/html
}

sbuffer = sbuffer + shttpversion + " 200 ok" + "\r\n";
sbuffer = sbuffer + "server: cx1193719-b\r\n";
sbuffer = sbuffer + "content-type: " + smimetype + "\r\n";
sbuffer = sbuffer + "accept-ranges: bytes\r\n";
sbuffer = sbuffer + "content-length: " + itotbytes + "\r\n\r\n";

byte[] heads = encoding.ascii.getbytes(sbuffer);


然后发送给对方,关闭socket。

复制代码 代码如下:

mysocket.send(heads, heads.length, 0);
mysocket.send(bytes, bytes.length, 0);

mysocket.close();