WCF Rest:不使用UriTemplate使用post方式传参解决HTTP400问题以及参数映射问题
在使用POST方式向服务提交数据时,出现HTTP400异常,以下代码描述:
服务接口定义:
[OperationContract]
[WebInvoke(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
Stream HelloData(MyData data);
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
Stream HelloDataStr(String data);
实现只是简单的把传入的数据打印出来,略
客户端调用:
方法一、
private static void HelloDataClient()
{
WebClient client = new WebClient();
client.Headers["Content-Type"] = "application/json";
string data = "{\"ID\":1,\"Name\":\"ss\"}";
string str = client.UploadString("http://localhost:1122/HelloData", "POST", data);
Console.WriteLine(str);
}
方法二
private static void HelloDataStrClient()
{
WebClient client = new WebClient();
string str = client.UploadString("http://localhost:1122/HelloDataStr", "POST", "ss");
Console.WriteLine(str);
}
以上两个方法对用调用两个不同的服务,问题在于使用Mydata数据契约的方法一OK,方法二出现HTTP400错误。为什么自定义类型的可以,而基本数据类型的不可以?起初认为自定义数据类型自己已经做了序列化,而string不是自己做的可能跟序列化有关。那没有用UriTemplate是不是参数映射出了问题?因为方法一已经成功,说明WCF会将HTTP请求参数默认映射到仅有的一个服务接口的参数上。排除此猜测。
方法后来做了以下迭代测试:
将方法二改为:
private static void HelloDataStrClient()
{
WebClient client = new WebClient();
string str = client.UploadString("http://localhost:1122/HelloDataStr", "POST", String.Empty);
Console.WriteLine(str);
}
发现调用成功,说明数据有问题。数据有问题就是数据的格式有问题,但是服务契约二没有声明Request的格式为JSON。那么他默认为什么呢?把方法二再改如下:
private static void HelloDataStrClient()
{
WebClient client = new WebClient();
client.Headers["Content-Type"] = "application/json";
string str = client.UploadString("http://localhost:1122/HelloDataStr", "POST", "\"ss\"");
Console.WriteLine(str);
}
调用成功。
注意:JSON格式默认为“”引起,所以 "\"ss\""不能写为“ss”,否则还是HTTP400错误。因为未识别数据,将数据拼接到其他字节了吧。
问题描述二、
没有使用UriTemplate做参数的映射,那多个参数是怎么映射的?将方法二改为:
服务契约二:
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped)]
Stream HelloDataStr(String data1,string data2);
客户端:
private static void HelloDataStrClient()
{
WebClient client = new WebClient();
client.Headers["Content-Type"] = "application/json";
string str = client.UploadString("http://localhost:1122/HelloDataStr", "POST", "{\"data1\":\"hh\",\"data2\":\"ss\"}");
Console.WriteLine(str);
}
调用成功,并且成功打印了两个参数。注意服务契约的接口定义属性WebMessageBodyStyle.Wrapped,此属性将两个参数进行了包装,否则无法映射。
附:JAVA调用代码:
public static void main(String[] args) {
// TODO Auto-generated method stub
HelloClient();
HelloDataClient();
HelloDataStrClient();
}
private static void HelloClient(){
URLClient client = new URLClient();
String resultStr = client.getDocumentAt("http://localhost:1122/Hello");
MyData data = assembleModel(resultStr);
System.out.print("Hello Response content: " +resultStr);
System.out.println("MyData Name: " +data.getName());
}
private static void HelloDataClient(){
try {
String postUrl = "http://localhost:1122/HelloData";
String postData = "{\"data1\":1,\"data2\":\"ss\"}";
HttpClient hClient = new DefaultHttpClient();
HttpPost post = new HttpPost(postUrl);
StringEntity s = new StringEntity(postData);
s.setContentEncoding("UTF-8");
s.setContentType("application/json");
post.setEntity(s);
HttpResponse response = hClient.execute(post);
HttpEntity responseEntity = response.getEntity();
String resultStr = inputStream2String(responseEntity.getContent());
MyData data = assembleModel(resultStr);
System.out.println("HelloDataStr Response content: "
+ resultStr);
System.out.println("MyData Name: " +data.getName());
} catch (Exception e) {
// TODO: handle exception
}
}
private static void HelloDataStrClient(){
try {
String postUrl = "http://localhost:1122/HelloDataStr";
String postData = "{\"data1\":1,\"data2\":\"ss\"}";
HttpClient hClient = new DefaultHttpClient();
HttpPost post = new HttpPost(postUrl);
StringEntity s = new StringEntity(postData);
s.setContentEncoding("UTF-8");
s.setContentType("application/json");
post.setEntity(s);
HttpResponse response = hClient.execute(post);
HttpEntity responseEntity = response.getEntity();
String resultStr = inputStream2String(responseEntity.getContent());
System.out.println("HelloDataStr Response content: "
+ resultStr);
} catch (Exception e) {
// TODO: handle exception
}
}
public static String inputStream2String(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int i = -1;
while ((i = is.read()) != -1) {
baos.write(i);
}
return baos.toString();
}
private static MyData assembleModel(String jsonStr) {
MyData model = null;
try {
JsonConvertor jsonConvertor = new JsonConvertor();
MyData[] stus = (MyData[]) jsonConvertor
.convertToObj(jsonStr,MyData.class);
model = stus[0];
} catch (Exception e) {
e.printStackTrace();
}
return model;
}
WCF Rest:不使用UriTemplate使用post方式传参解决HTTP400问题以及参数映射问题的更多相关文章
- 二十一、springboot之定制URL匹配规则(项目中遇到的问题:get方式传参,带有小数点,被忽略)
一.问题描述: get方式传参,在传送价格,积分时(带有小数点),debug后台微服务接受到的参数,却不带小数点,如:price是0.55,后台接受后却是0 二.解决 在WebConfiguratio ...
- 使用Fiddler工具发送post请求(带有json数据)以及get请求(Header方式传参)
Fiddler工具是一个http协议调试代理工具,它可以帮助程序员测试或调试程序,辅助web开发. Fiddler工具可以发送向服务端发送特定的HTTP请求以及接受服务器回应的请求和数据,是web调试 ...
- 同一路由带参刷新,以及params和query两种方式传参的异同
同一路由应该不叫跳转了吧,就先叫刷新好了. 需求及问题 今天做web课设有这样一个需求: 在导航栏中一项叫做教师队伍一级菜单下,有三个二级菜单,分别为教授.副教授.讲师.这三个二级菜单分别对应一个页面 ...
- vue:子组件通过调用父组件的方法的方式传参
在本案例中,由于子组件通过调用父组件的方法的方式传参,从而实现修改父组件data中的对象,所以需要啊使用$forceUpdate()进行强制刷新 父组件: provide() { return { s ...
- RESTful Get方式传参json格式后端400 解决方案
前端采用vue+axios 后端采用spring boot restful 问题: 前端get 请求需要传递array 字段值 后端由于tomcat 版本问题,不支持url接受特殊字符包括 [] {} ...
- python flask学习第2天 URL中两种方式传参
新创建项目 自己写个url映射到自定义的视图函数 在url中传递参数 app.py from flask import Flask app = Flask(__name__) @app.route ...
- 在 WinForm 中打开页面采用POST方式传参http。可以多个参数传递,返回json字符串
//调用方法 Dictionary<string, string> postData = new Dictionary<string, string>(); postData. ...
- window.open打开新窗体并用post方式传参
function openPostWindow(url,data,name){ //url要跳转到的页面,data要传递的数据,name显示方式(可能任意命名) var tempForm = docu ...
- yii2.0的gradview点击按钮通过get方式传参
1.直接看views层里的代码就可以了 , <!--?= GridView::widget([ 'dataProvider' =--> $dataProvider, 'filterMode ...
随机推荐
- (转)SQL Server 触发器
SQL Server 触发器 触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 ...
- mysql的join
SELECT * FROM a LEFT JOIN b ON a.aID = b.bID; a为主,a的数据全显示,连不上b的对应字段为空 SELECT * FROM a RIGHT JOIN ...
- 简单实用的HTML代码
简单实用的HTML代码 一.HTML各种命令的代码: 1.文本标签(命令) <pre></pre> 创建预格式化文本 <h1></h1> 创建最大的标题 ...
- 2015网易校招Java开发工程师(技术架构)在线笔试题
1. 程序和进程的本质区别是? A.在外存和内存存储 B.非顺序和顺序执行机器指令 C.独占使用和分时使用计算机资源 D.静态和动态特征 参考答案分析: 进程与应用程序的区别: 进程(Process ...
- MVC 中使用uploadify上传图片遇到的蛋疼问题
MVC 中使用uploadify上传图片遇到的蛋疼问题 初次使用uploadify上传图片,遇到了一些比较纠结的问题,在这里和大家分享下,有不对的地方还望大神多多指教,希望对刚接触的朋友有所帮助,文采 ...
- VS2005快捷键
VS2005快捷键 CTRL + SHIFT + B生成解决方案 CTRL + F7 生成编译 CTRL + O 打开文件 CTRL + SHIFT + O打开项目 CTRL + SHIFT + C显 ...
- linux多线程编程之互斥锁
多线程并行运行,共享同一种互斥资源时,需要上互斥锁来运行,主要是用到pthread_mutex_lock函数和pthread_mutex_unlock函数对线程进行上锁和解锁 下面是一个例子: #in ...
- BZOJ 1458 士兵占领
http://www.lydsy.com/JudgeOnline/problem.php?id=1458 题意:n x m的棋盘,k个位置不能放,每行和每列都有要求至少的士兵,求能否有最少的满足条件的 ...
- TENX_ASM.uew
/L14"TENX ASM" Nocase Line Comment = ; File Extensions = INC ASM LST H /Colors = ,,,,, /Co ...
- CSS基础-引入方法,选择器,继承
一.CSS引入方法:行内式.嵌入式.导入式.链接式. 1.行内式. 即:在标签的style属性中设定CSS样式. 例子:<div style="行内式</div> 2.嵌入 ...