C#使用Http Post方式传递Json数据字符串调用Web Service
引言
前段时间一直在做一个erp系统,随着系统功能的完善,客户端(cs模式)变得越来越臃肿。现在想将业务逻辑层以下部分和界面层分离,使用web service来做。由于c#中通过直接添加引用的方来调用web service的方式不够灵活,故采取手动发送http请求的方式来调用web service。最后选择使用post方式来调用web service,至于安全性和效率暂不考虑。在学习使用的过程,遇到了很多问题,也花了很长时间来解决,网上相关的帖子很少,如果各位在使用的过程中有一些问题难以解决,可以找我哦。
前提
使用post方式调用web service,需要在服务项目配置文件web.config中添加使用http协议的配置,在<system.web>标签中添加<webservices> <protocols> <add name= "httppost"/></protocols></webservices>配置,同时我们还可以添加<customerrors mode="off" />配置,这样可以在服务方法的返回值带出服务方法调用的异常信息,异常信息同样以xml的形式返回,这样便于客户端进行调试。
web service接口方法
[webmethod] public string project(string paramaters) { return paramaters; }
实现代码
public string post(string methodname, string jsonparas) { string strurl = url + "/" + methodname; //创建一个http请求 httpwebrequest request = (httpwebrequest)webrequest.create(strurl); //post请求方式 request.method = "post"; //内容类型 request.contenttype = "application/x-www-form-urlencoded"; //设置参数,并进行url编码 //虽然我们需要传递给服务器端的实际参数是jsonparas(格式:[{\"userid\":\"0206001\",\"username\":\"ceshi\"}]), //但是需要将该字符串参数构造成键值对的形式(注:"paramaters=[{\"userid\":\"0206001\",\"username\":\"ceshi\"}]"), //其中键paramaters为webservice接口函数的参数名,值为经过序列化的json数据字符串 //最后将字符串参数进行url编码 string paraurlcoded = system.web.httputility.urlencode("paramaters"); paraurlcoded += "=" + system.web.httputility.urlencode(jsonparas); byte[] payload; //将json字符串转化为字节 payload = system.text.encoding.utf8.getbytes(paraurlcoded); //设置请求的contentlength request.contentlength = payload.length; //发送请求,获得请求流 stream writer; try { writer = request.getrequeststream();//获取用于写入请求数据的stream对象 } catch (exception) { writer = null; console.write("连接服务器失败!"); } //将请求参数写入流 writer.write(payload, 0, payload.length); writer.close();//关闭请求流 string strvalue = "";//strvalue为http响应所返回的字符流 httpwebresponse response; try { //获得响应流 response = (httpwebresponse)request.getresponse(); } catch (webexception ex) { response = ex.response as httpwebresponse; } stream s = response.getresponsestream(); //服务器端返回的是一个xml格式的字符串,xml的content才是我们所需要的json数据 xmltextreader reader = new xmltextreader(s); reader.movetocontent(); strvalue = reader.readinnerxml();//取出content中的json数据 reader.close(); s.close(); return strvalue;//返回json数据 }
url的格式样例: "http://59.68.29.106:8087/ift_project.asmx"
methodname参数就是"project"
jsonparas就是使用c# javascriptserializer将list<object>类型的对象序列化之后得到的值,数据格式:[{\"userid\":\"0206001\",\"username\":\"ceshi\"}],json数据中的中括号代表由着多个对象集合序列化,花括号代表一个对象序列化得到的结果,花括号里面的内容使用键值对的方式展示,多个属性之间用逗号隔开,每个对象也用逗号隔开。
request.contenttype必须设置值,建议使用"application/x-www-form-urlencoded",设置其他值就很容易报服务器内部异常,使用这种方式服务接口方法返回的是xml格式的字符串
payload将请求参数转换成二进制来保存,此处一定要将“paramaters”加入其中,不然会报异常缺少参数,paramaters就是服务接口函数的参数名。函数中使用了url编码,注意在编码的时候只需要将键和值进行编码,不要将中间的=进行编码,不然getresponse的时候会报异常。
request.contentlength也是必须设置的值
在得到响应流之后stream s = response.getresponsestream();需要使用reader来解析响应流,这个地方我使用的是xmltextreader,因为我服务方法返回的是xml格式的字符串,其中json数据在xml的content中。在取出json数据之后,再进行相应的反序列化即可得到对象。
小结
在学习使用post调用方式的过程中,查看了一些帖子,但是网上的帖子很少,不少帖子中也给出了一下post方法的样例,给出的很多post方法没有明确给出传入字符串的格式,导致我的传入参数jsonparas缺少了键paramaters,测试调试了很久才发现这个错误,最终差点放弃了。还有contenttype的设置也很重要,使用其他的值对传入参数的要求很高,初学者不建议使用其他方式。初期使用post方式的时候,在getresponse()处容易报异常,可以设置customererrors mode将异常信息返回给客户端,这样容易调试。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: java中Class.forName方法的作用详解
下一篇: Java的SPI机制实例详解