在使用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问题以及参数映射问题的更多相关文章

  1. 二十一、springboot之定制URL匹配规则(项目中遇到的问题:get方式传参,带有小数点,被忽略)

    一.问题描述: get方式传参,在传送价格,积分时(带有小数点),debug后台微服务接受到的参数,却不带小数点,如:price是0.55,后台接受后却是0 二.解决 在WebConfiguratio ...

  2. 使用Fiddler工具发送post请求(带有json数据)以及get请求(Header方式传参)

    Fiddler工具是一个http协议调试代理工具,它可以帮助程序员测试或调试程序,辅助web开发. Fiddler工具可以发送向服务端发送特定的HTTP请求以及接受服务器回应的请求和数据,是web调试 ...

  3. 同一路由带参刷新,以及params和query两种方式传参的异同

    同一路由应该不叫跳转了吧,就先叫刷新好了. 需求及问题 今天做web课设有这样一个需求: 在导航栏中一项叫做教师队伍一级菜单下,有三个二级菜单,分别为教授.副教授.讲师.这三个二级菜单分别对应一个页面 ...

  4. vue:子组件通过调用父组件的方法的方式传参

    在本案例中,由于子组件通过调用父组件的方法的方式传参,从而实现修改父组件data中的对象,所以需要啊使用$forceUpdate()进行强制刷新 父组件: provide() { return { s ...

  5. RESTful Get方式传参json格式后端400 解决方案

    前端采用vue+axios 后端采用spring boot restful 问题: 前端get 请求需要传递array 字段值 后端由于tomcat 版本问题,不支持url接受特殊字符包括 [] {} ...

  6. python flask学习第2天 URL中两种方式传参

    新创建项目   自己写个url映射到自定义的视图函数 在url中传递参数 app.py from flask import Flask app = Flask(__name__) @app.route ...

  7. 在 WinForm 中打开页面采用POST方式传参http。可以多个参数传递,返回json字符串

    //调用方法 Dictionary<string, string> postData = new Dictionary<string, string>(); postData. ...

  8. window.open打开新窗体并用post方式传参

    function openPostWindow(url,data,name){ //url要跳转到的页面,data要传递的数据,name显示方式(可能任意命名) var tempForm = docu ...

  9. yii2.0的gradview点击按钮通过get方式传参

    1.直接看views层里的代码就可以了 , <!--?= GridView::widget([ 'dataProvider' =--> $dataProvider, 'filterMode ...

随机推荐

  1. java面试大全

    JAVA相关基础知识1.面向对象的特征有哪些方面 1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分,暂时 ...

  2. ASP.NET网站与ASP.NET应用程序的区别

    我们使用VS做ASP.NET的时候,可以选择新建ASP.NET应用程序,同时也可以新建ASP.NET网站,两者有什么具体区别呢?今天真是很幸运,比别人多上了老师一节课,讲的是这两者之间的一些区别.我学 ...

  3. asp.net断点续传技术---下载(转)

    断点续传的原理 在了解HTTP断点续传的原理之前,先来说说HTTP协议,HTTP协议是一种基于tcp的简单协议,分为请求和回复两种.请求协议是由客户机(浏览器)向服务器(WEB SERVER)提交请求 ...

  4. javascript 高级程序设计学习笔记(面向对象的程序设计) 1

    Object构造函数或对象字面量都可以用来创建对象,但这些方式有个明显的缺点:使用相同一个接口创建很多对象,会产生大量重复代码. 工厂模式 //工厂模式 function createDog (nam ...

  5. codeforces 340D Bubble Sort Graph(dp,LIS)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud  Bubble Sort Graph Iahub recently has lea ...

  6. js原生Ajax的封装与使用

    一.原生Ajax代码的封装如下: (function() { var XHR = { createStandardXHR: function() { return new XMLHttpRequest ...

  7. https://github.com/aptana/studio3/releases aptana

    https://github.com/aptana/studio3/releases  aptana

  8. uWSGI

    参考:http://perlmaven.com/deploying-pyton-with-uwsgi-on-ubuntu-13-10

  9. 蘑菇街2015校招技术类笔试题A卷,回忆版(杭州站)

    笔试时间:10月9号 下午 1.一串数据的最大递增序列,输出个数 例如 4,2, 6,3, 1,5, 最大递增序列为, 2,3, 5,输出3, 2.求两个整型数据集合的交集,尽可能少用时间. 假设两个 ...

  10. 海量数据处理利器greenplum——初识

    简介及适用场景 如果想在数据仓库中快速查询结果,可以使用greenplum. Greenplum数据库也简称GPDB.它拥有丰富的特性: 第一,完善的标准支持:GPDB完全支持ANSI SQL 200 ...