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

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

学无止境,精益求精

   上一节讲述了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. [DX11] Introduction

    http://www.cnblogs.com/clayman/archive/2011/10/18/2216889.html The Beauty of DirectX 11

  2. 通过SocketLog快速分析OneThink程序

    通过SocketLog快速分析OneThink程序 http://www.thinkphp.cn/topic/10846.html   浏览:2332 发布日期:2014/02/08 分类:技术分享 ...

  3. C++ 构造函数放置默认转换explicit关键字(2)

    按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面所示: class String { String ( const char* p );  ...

  4. Socket简介

    本文全部摘抄http://c.biancheng.net/cpp/html/3029.html 大多数项目是在Linux下开发服务器端,而在Windows下开发客户端,需要经常在两大平台之间进行切换, ...

  5. Oracle 数据库安装

    下载 www.oracle.com ->Downloads -> Oracle Database 安装: 解压到同一文件夹下 仅安装数据库软件 单实例数据库安装 企业版 oracle基目录 ...

  6. image hover

    http://www.nxworld.net/tips/css-image-hover-effects.html

  7. MySQL主从架构之Master-Master互为主备

    前言 通常,为了简化逻辑,master会设置为只读,正常只通过slave进行读写. 若要两边都写,为了避免自增id冲突,一般会设置奇偶错开,即一台的自增ID均为奇数,另一台均为偶数. 基本原理 首先, ...

  8. js 定时跳转, 格式化字符串时间

    效果 1.js中将一字符串表示的系统时间转换为Date时间对象 //js中将一串字符串转换为date类型,主要是先过滤字符,然后分割开 function parseToDate(strTime) { ...

  9. 关于Memo或者Edit之类控件, 直接设置Text无法撤销的解决方案

    昨天看到群里有人问使用Memo1.Text := '11111';来设置内容的代码无法使用Memo1.Undo的方式来撤销 测试了一下果然如此, 跟踪了VCL代码, 发现Text := '11111' ...

  10. FTS抓包看AVDTP

    1.概述   测试过程为打开Audio连接,没有听音乐,人后断开Audio连接,主要目的是为了测试AVDTP的工作流程.   2.Frame分析    首先贴出抓取的关于AVDTP的包: 在L2CAP ...