最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来。

十年河东十年河西,莫欺少年穷。 

学无止境,精益求精

   上一节讲述了C# WebApi传参之Get请求-AJAX

本节讲述C# WebApi传参之Post请求-AJAX,说起Ajax针对webApi的Post请求,真的不敢恭维,确实比较怪异,如果你不幸要写一个Ajax Post请求webApi接口,那么您还是有必要花点时间看看本篇博客,如果你也遇到了同样的问题,就不妨在最后给本篇博客点个赞。谢谢

说起Post请求,想必大家都比较熟悉,post请求原理和get请求不一样,我们知道get请求的参数是通过url来传递的,而post请求则是通过http的请求体中传过来的,WebApi的post请求也需要从http的请求体里面去取参数。说白了Get请求是通过URL传递一组键值对,Post请求是发送一个Http请求体。上一节Get请求,我们用到了[FromUri]关键字。本节的Post请求,我们将使用另一个关键字[FromBoay],上一节结尾我建议大家Get请求时要带上[FromUri]关键字,同理,本节的Post请求,我要建议大家在接收参数时,带上[FromBody]关键字,毕竟养成一个好的习惯不是什么坏事。

开篇中提到,Ajax Post请求webApi很怪异,那么它究竟怎么怪异呢?下面以代码示范说明:<本文仍旧采用上一节Get请求的实体对象,不知道的博友,请参阅我的上篇博客>

如下:

        /// <summary>
/// 简单测试案例
/// </summary>
/// <returns></returns>
[HttpPost]
public string Get()
{
return "OK";
}
/// <summary>
/// 通过id获取特定数据
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpPost]
public string GetById([FromBody]int Id)
{
list = list.Where(p => p.Id == Id).ToList();
return JsonHelper.JsonSerializer<List<Person>>(list);
}

aJax如下

        //无参数请求-简单示例
$(document).ready(function () {
$.ajax({
url: "http://localhost:9953/api/Person/Get",
type: "post",
contentType: "application/json",
dataType: "text",
data:{},
success: function (result,status) {
if (status == "success") {
alert(result);
}
},
error: function (error) {
alert(error);
}
});
});
//单个参数传递- data: {"":"3"}, 这种方式也竟然正确
$(document).ready(function (data) {
$.ajax({
url: "http://localhost:9953/api/Person/GetById",
type: "post",
contentType: "application/json",
dataType: "text",
data: {Id:""},
success: function (result,status) {
alert(result)
},
error: function (error) {
alert(error);
}
});
});

上文JS中注释有这么一句话:‘data: {"":"3"}, 这种方式也竟然正确’

这是一种另许多人头痛的写法,但是没办法,经过测试,这种写法确实很正确。

根据上述案例,我们看到了Post请求传递单个参数的写法,那么如果传递多个参数,我们能否采取如下的方法?(经测试,如下写法是错误的,报404Not Found)

  $(document).ready(function (data) {
$.ajax({
url: "http://localhost:9953/api/Person/GetByIdAndSex",
type: "post",
contentType: "application/json",
dataType: "text",
data: { Id: "",Sex:"W" },
success: function (result, status) {
alert(result)
},
error: function (error) {
alert(error);
}
});
});
        /// <summary>
/// 错误的写法 当然,本篇只讲解Ajax请求,如果你是通过HttpwebClient的方式进行请求,这种写法是没有任何问题的
/// </summary>
/// <param name="Json"></param>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage GetByIdAndSex([FromBody]string Id,[FromBody]string Sex)
{
List<Person> list_2 = new List<Person>();
var Result = from r in list
where r.Id == Convert.ToInt32(Id) && r.Sex == Sex
select r;
foreach (var Item in Result)
{
list_2.Add(Item);
}
return ResultToJson.toJson(list_2);
}

测试的结果是:获取不到Id 和 Sex 的值!开篇我们说到,Get的请求方式是通过URL传递键值对,而Post 请求传递的是一个Http请求体,而JS中 data: { Id: "3",Sex:"W" }, 采用的是键值对类型,而Post请求是不能读取键值对滴。故:上述写法不对。

那么,你可能会问,为什么一个参数请求的时候没有问题,为什么两个参数就不行了呢?这个...我能作的解答是:这就是Post Ajax请求的怪异之处。

正确的写法该当如何呢?

我们知道:Get请求传递兼职对,Post请求传递的是Http的请求体,按照本人的理解就是:Post请求需要发送一个参数作为Http请求体,这个参数为一个整体,而非一组键值对、故而,我们作如下改动:

代码如下:

 //多个参数传递
$(document).ready(function (data) {
$.ajax({
url: "http://localhost:9953/api/Person/GetByIdAndSex",
type: "post",
contentType: "application/json",
dataType: "text",
data: JSON.stringify({ Id: "3",Sex:"W" }),
success: function (result, status) {
alert(result)
},
error: function (error) {
alert(error);
}
});
});
        /// <summary>
/// 错误的写法2 怪异吧
/// </summary>
/// <param name="Json"></param>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage GetByIdAndSex([FromBody]string Json)
{
string Id = JsonHelper.GetJsonValue(Json, "Id");//获取Id
string Sex = JsonHelper.GetJsonValue(Json, "Sex");//获取sex
List<Person> list_2 = new List<Person>();
var Result = from r in list
where r.Id == Convert.ToInt32(Id) && r.Sex == Sex
select r;
foreach (var Item in Result)
{
list_2.Add(Item);
}
return ResultToJson.toJson(list_2);
}

如上注释为红色加粗的JS代码,我们将Post的键值对转化为Json字符串传递到后端。而后端代码中,我们尝试接收这个JSon字符串,并作解析,从中读出Id和Sex的值,按照Post请求规则,我们也是只发送了一个Http请求体,并且在后端作了接收。这次应该没有问题了吧?

实际测试的结果是:不会发生404 Not Found 错误,但是接收不到Post的字符串,也就是 [FromBody]string Json 中的Json为Null,(⊙o⊙)…

靠,这样都不行,那到底怎么能行呢?

下班了,不多喷了,直接告诉大家几点注意事项:

后端接收时,参数类型应采用dynamic,JS代码中,必须加上contentType对应的类型,Post的值必须为一个整体,而不能是键值对。JS中Type类型必须为Post ,后端接收类型必须为:[HttpPost],如果不加,则会默认为[HttpGet]方式。

以下是代码示例,希望能帮助大家:

1、多个参数传递:

 //多个参数传递
$(document).ready(function (data) {
$.ajax({
url: "http://localhost:9953/api/Person/GetByIdAndSex",
type: "post",
contentType: "application/json",
dataType: "text",
data: JSON.stringify({ Id: "",Sex:"W" }),
success: function (result, status) {
alert(result)
},
error: function (error) {
alert(error);
}
});
});
 [HttpPost]
public HttpResponseMessage GetByIdAndSex([FromBody]dynamic Json)
{
string Id = Json.Id;
string Sex = Json.Sex;
List<Person> list_2 = new List<Person>();
var Result = from r in list
where r.Id == Convert.ToInt32(Id) && r.Sex == Sex
select r;
foreach (var Item in Result)
{
list_2.Add(Item);
}
return ResultToJson.toJson(list_2);
}

2、传递一个对象数据

       //传递对象数组
$(document).ready(function (data) {
var dataList = [{ Id: "", Sex: "男", Name: "陈卧龙", Age: "" },
{ Id: "", Sex: "男", Name: "陈大龙", Age: "" },
{ Id: "", Sex: "男", Name: "陈小龙", Age: "" }];
$.ajax({
url: "http://localhost:9953/api/Person/GetByObjectList",
type: "post",
contentType: "application/json",
dataType: "text",
data: JSON.stringify(dataList),
success: function (result, status) {
alert(result)
},
error: function (error) {
alert(error);
}
});
});
/// <summary>
/// 对象数组作为参数
/// </summary>
/// <param name="P"></param>
/// <returns></returns>
[HttpPost]
public HttpResponseMessage GetByObjectList([FromBody]dynamic Plist)
{
List<Person> list = new List<Person>();
foreach (var item in Plist)
{
Person person = new Person()
{
Name = item.Name,
Sex = item.Sex,
Id = item.Id,
Age = item.Age,
};
list.Add(person);
}
return ResultToJson.toJson(list);
}

到此为止:pOst请求也就讲完了

我们知道有四大请求:Get,Post,Put,Delete ,其中Put、delete请求都是采用的Post请求原理,他们直接大同小异,无非就是Put请求做修改 插入,Delete请求作删除。因此:Put Delete 请求均可采用本文中的请求方式,只是他们所作的动作不一样罢了!

好了,回家清蒸鱼喽,最近学的拿手好菜,有喜欢的,欢迎品尝,我们你们邮递!哈哈,看了不评论,不点赞,不是好同志!

@陈卧龙的博客

C# WebApi传参之Post请求-AJAX的更多相关文章

  1. C# WebApi传参之Get请求-AJAX

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷.  学无止境,精益求精    在介绍本篇博客之前,先来温故下AJax的请求, ...

  2. WebApi传参总动员(四)

    前文介绍了Form Data 形式传参,本文介绍json传参. WebApi及Model: public class ValuesController : ApiController { [HttpP ...

  3. WebApi传参总动员(一)

    目前自己的工作和WebApi相关,免不了传入.接收参数.以前的老办法是从请求流中获取json,再反序列化,这中间有2个不能控制的地方,一个是流,一个是反序列化,都需要try,总感觉非常的不爽.因此对W ...

  4. WebApi传参总动员(三)

    上篇介绍了如何从输入流中获取实体对象.本篇介绍以url形式传递参数.简单的参数不再赘述,这里主要实现形如(string name,Woman woman)这样的参数传递. 本篇及后面几章均涉及js调用 ...

  5. WebAPI传参

    1.GET请求传递参数 URL传参:http://localhost/ApiTest/test?id=1 API接收参数 [HttpGet] public string GetUser(int id) ...

  6. C#进阶系列——WebApi 传参详解

    本篇打算通过get.post.put.delete四种请求方式分别谈谈基础类型(包括int/string/datetime等).实体.数组等类型的参数如何传递. 回到顶部 一.get请求 对于取数据, ...

  7. WebApi传参总动员(五)

    上回说到涉及多个实体的传参,用常规的方法已经不能解决了.这回我们用终极大招搞定她. WebApi:注意要引用JSON.Net [HttpPost] public string GetData(stri ...

  8. WebApi传参总动员(填坑)

    本以为系列文章已经Over,突然记起来前面留了个大坑还没填,真是自己给自己挖坑. 这个坑就是: (body 只能被读取一次)Only one thing can read the body MVC和W ...

  9. WebApi传参总动员(二)

    上篇,从最简单的string入手.本篇演示了从请求的输入流中获取实体.api: public class ValuesController : ApiController { [HttpPost] p ...

随机推荐

  1. NVPerfHUD

    http://www.cnblogs.com/cproom/archive/2006/11/13/559287.html NVPerfHUD是一个很好的3D程序调试工具,它是NVPerfKit的一部分 ...

  2. switch parser.p4源码

    /* Copyright 2013-present Barefoot Networks, Inc. Licensed under the Apache License, Version 2.0 (th ...

  3. 20145225 实验四《Andoid开发基础》

    实验内容 搭建Android环境 运行Android 修改代码,能输出学号 实验步骤 安装Android Studio 安装Android的SDK 运行Andriod Studio并在模拟手机上显示自 ...

  4. jsonObject jsonarray

    1.JAR包简介 要使程序可以运行必须引入JSON-lib包,JSON-lib包同时依赖于以下的JAR包: commons-lang.jar commons-beanutils.jar commons ...

  5. 【转】 Build a RESTful Web service using Jersey and Apache Tomcat 2009

    Build a RESTful Web service using Jersey and Apache Tomcat Yi Ming Huang with Dong Fei Wu, Qing GuoP ...

  6. java effective 读书笔记

    java effective 读书笔记 []创建和销毁对象 静态工厂方法 就是“封装了底层 暴露出一个访问接口 ” 门面模式 多参数时 用构建器,就是用个内部类 再让内部类提供构造好的对象 枚举 si ...

  7. Qt获取屏幕分辨率

    http://my.oschina.net/u/1255773/blog/159557 原 Qt获取屏幕分辨率 发表于1年前(2013-09-06 11:00)   阅读(546) | 评论(0) 3 ...

  8. CC254x(cc2540/cc2541)的微信AirSync调试笔记

    一.前言 本尊自诩为IOT小能手,一直没涉足蓝牙实在说不过去.刚好上个月底的时候计划做个BLE设备,这阵子利用业余时间自学了BLE协议栈,了解了GATT,磕磕绊绊完成CC254x(cc2540/cc2 ...

  9. 蓝牙 BLE GATT 剖析(一)

    一.概述 The Generic Attribute Profile (GATT) defines a service framework using the Attribute Protocol. ...

  10. 使用SVN提示“工作副本已经锁定”的解决办法

    更新或者提交前执行一下clean up.如果在当前目录执行该命令后,仍然提示锁定,就到上一层目录再执行下...