WebApi Post 后台无法获取参数的解决方案
事件回放:
之前一段时间,公司里前端用的Angularjs 发送http请求也是用的ng的组件,后台是.Net的WebApi
前端
var data = {
PArgs: {
PageIndex: 0,
PageSize: 8,
RowsCount: 0
}
};
$http.post("/Api/Test/ABC", data).success(function (data) {
console.log(data)
});
后台接收
using SignalRDemo.VModel;
using System.Web.Http; namespace SignalRDemo.Api
{
public class TestController : ApiController
{
[HttpPost]
public object ABC([FromBody]MMCourse model)
{
return model;
}
}
}
具体的Model是这样子的
using System; namespace SignalRDemo.VModel
{
public class MMCourse : BaseModel
{
//上传分页
public PagerArgs PArgs { set; get; }
} public sealed class PagerArgs
{
/// <summary>
/// 分页
/// </summary>
/// <param name="pageIndex">每页数据条数</param>
/// <param name="pageSize">数据总行数</param>
public PagerArgs(int pageIndex, int pageSize)
{
this.PageIndex = pageIndex;
this.PageSize = pageSize;
} /// <summary>
/// 当前页索引
/// </summary>
public int PageIndex { get; set; } /// <summary>
/// 每页数据条数
/// </summary>
public int PageSize { get; set; }
}
}
Model
流程就是后台建好实体类,创建接口
前台指定要访问的接口,传入与后台接收参数的实体类结构相同的对象,后台就能接收到这个数据。运行正常。
后来 某一新建页面 前台没有使用Angularjs,而是用的jQuery,访问同一接口,突然发现 后台接收到的参数一直是null。
WebApi Post方式 怎么会无法获取参数呢?
通过查看控制台的http请求和后台的数据,经过不断的摸索,依次发现几个解决方法,也伴随着一些诡异事件:
方案①
首先 后台肯定是成功接收到了请求的,但是由于某种原因,接口方法的输入参数没有值。
初步判断跟类型转换有关,将接收类型改为JObject,就能收到数据了,然后再序列化->反序列化
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SignalRDemo.VModel;
using System.Web.Http; namespace SignalRDemo.Api
{
public class TestController : ApiController
{
[HttpPost]
public object ABC([FromBody]JObject model)
{
return JsonConvert.DeserializeObject<MMCourse>(JsonConvert.SerializeObject(model));
}
}
}
方案②经过修改参数发现,在不改动后台的情况下,如果参数是
var data = {
A:1
};
后台收到的数据结构是这样的
{
Pargs:{
PageIndex:0,
PageSize:0
}
}
不管怎样,数据还是能传递过去,只是webapi将参数转换的时候应该是出了问题。
回头仔细看了一下后台实体类,发现PagerArgs类有一个构造函数 还是要有两个参数的。试着添加了一个无参构造,发现数据能够正常获取了!
这个如果要深究的话 就要研究webapi底层对字符串的反序列化处理了,暂时忽略。
方案③
虽然通过上面两种方式可以迂回解决问题,但是心里还纠结着一个问题:为毛用Ng的$http.post一直没事,换了jQuery.post就发生这么多事?
开始对比两种方式的请求信息


点击数据上方的【view source】 查看发送的字符串
ng :
{"PArgs":{"PageIndex":0,"PageSize":8,"RowsCount":0}}
jq:
PArgs%5BPageIndex%5D=0&PArgs%5BPageSize%5D=8&PArgs%5BRowsCount%5D=0
decode之后是
PArgs[PageIndex]=0&PArgs[PageSize]=8&PArgs[RowsCount]=0
ng发送的数据跟预想中是一样的 跟发送的对象保持一直的json结构。
但是 jq发送的怎么会成了这种模样?此外 Request Payload跟Form Data又是什么?是Content-Type的区别引起的这些么?
通过查看jq.ajax的Api 找到下面一段

说的就是 如果使用的是post 默认的contentType是“application/x-www-form-urlencoded;charset=UTF-8“,
如果contentType是"..form..",则发送数据的是Form Data
如果是”application/json“ ,则是Request Payload。
而使用这种内容类型时,会把数据用$.param()转换一次之后再发送。

跟用之前用jq发送的数据内容完全匹配,就是这个原因了。
那这样处理起来就简单了,只需要发送数据前设置contentType="application/json;charset=UTF-8"就可以了。
还有一点要注意的是 ajax是不会发送对象的 最终都要转换成字符串。所以发送的时候需要人为的处理一下。
var data = {
PArgs: {
PageIndex: 0,
PageSize: 8,
RowsCount: 0
}
};
$.ajaxSetup({
contentType: "application/json;charset=UTF-8"
})
$.post("/Api/Test/ABC", JSON.stringify(data), function (rst) {
//TODO
}, "json");
或者
$.ajax({
url: "/Api/Test/ABC",
dataType: "json",
type: "post",
contentType: "application/json;charset=UTF-8",
data: JSON.stringify(data),
success: function (rst) {
console.log(rst);
}
})
WebApi Post 后台无法获取参数的解决方案的更多相关文章
- springMVC --@RequestParam注解(后台控制器获取参数)
在SpringMVC后台控制层获取参数的方式主要有两种,一种是request.getParameter("name"),另外一种是用注解@RequestParam直接获取. 1.获 ...
- asp.net webapi 的Request如何获取参数
public class BaseApiController : ApiController { private HttpRequestBase _request; /// 全局Requests对象 ...
- JSP基础知识➣获取参数和过滤器(四)
JSP表单提交和参数获取 JSP表单提交的两种方式:post和get,通过这两种方式提交的参数到后台,获取参数的值主要由request来处理,获取值的方式有以下几种: getParameter(): ...
- SpringMVC控制器接收不了PUT提交的参数的解决方案
摘要: SpringMVC控制器接收不了PUT提交的参数的解决方案 这次改造了下框架,把控制器的API全部REST化,不做不知道,SpringMVC的REST有各种坑让你去跳,顺利绕过它们花了我不少时 ...
- axios 发 post 请求,后端接收不到参数的解决方案
问题场景 场景很简单,就是一个正常 axios post 请求: axios({ headers: { 'deviceCode': 'A95ZEF1-47B5-AC90BF3' }, method: ...
- axios 发 post 请求,后端接收不到参数的解决方案(转载)
原文地址:https://www.cnblogs.com/yiyi17/p/9409249.html 问题场景 场景很简单,就是一个正常 axios post 请求: axios({ headers: ...
- Servlet生命周期以及获取参数
1. 创建Servlet几种方式 1) 实现Servlet接口 控制Servlet的生命周期 构造器 init() service() des ...
- WebAPI下的如何实现参数绑定
本文将概述在WebAPI方式下将如何将参数绑定到一个action方法,包括参数是如何被读取,一系列规则决定特定环境采用的那种绑定方式,文章最后将给出一些实际的例子. Parameter binding ...
- [一步一步MVC]第二回:还是ActionFilter,实现对业务逻辑的统一Authorize处理 OnActionExecuting内如何获取参数
如何获取参数:http://www.cnblogs.com/anytao/archive/2009/04/23/anytao-mvc-02-actionauthorize.html 由问题引出 在AS ...
随机推荐
- HuffmanTree的浅析和在C#中的算法实现
无论是在我们的开发项目中,还是在我们的日常生活中,都会较多的涉及到文件压缩.谈到文件压缩,可能会有人想问文件压缩到底是怎么实现的,实现的原理是什么,对于开发人员来说,怎么实现这样一个压缩的功能. 接下 ...
- Android应用底部导航栏(选项卡)实例
现在很多android的应用都采用底部导航栏的功能,这样可以使得用户在使用过程中随意切换不同的页面,现在我采用TabHost组件来自定义一个底部的导航栏的功能. 我们先看下该demo实例的框架图: 其 ...
- Circuit Breaker Pattern(断路器模式)
Handle faults that may take a variable amount of time to rectify when connecting to a remote service ...
- SQL Server 存储(1/8):理解数据页结构
我们都很清楚SQL Server用8KB 的页来存储数据,并且在SQL Server里磁盘 I/O 操作在页级执行.也就是说,SQL Server 读取或写入所有数据页.页有不同的类型,像数据页,GA ...
- C#程序开发中经常遇到的10条实用的代码
1 读取操作系统和CLR的版本 OperatingSystem os = System.Environment.OSVersion; Console.WriteLine("Platform: ...
- LINQ to SQL语句(16)之对象标识
对象标识 运行库中的对象具有唯一标识.引用同一对象的两个变量实际上是引用此对象的同一实例.你更改一个变量后,可以通过另一个变量看到这些更改. 关系数据库表中的行不具有唯一标识.由于每一行都具有唯一的主 ...
- Devexpress WPF Theme Editor 02
Devexpress WPF Theme Editor 01 对于上次我们生成的主题 开始添加到我们的项目中. 运行Visual Studio和打开一个WPF解决方案,你想申请的主题. 添加的主题集会 ...
- 好的Ui界面地址
http://121.40.148.178:8080/http://www.uimaker.com/http://www.uimaker.com/uimakerhtml/bshtml/124261.h ...
- 微信扫码支付~官方DEMO的坑~参数不能自定义
返回目录 由于微信在校验参数时采用了“微信服务端”校验,它的参数是前期定义好的,所以用户不能自己添加自定义的参数,你可以把参数写在Attach字段时,作为它的附加参数. 参数和返回值定义如下: pub ...
- Python中三目计算符的正确用法及短路逻辑
今天在看别人代码时看到这样一种写法, 感觉是个挺容易踩到的坑, 搞清楚后写出来备忘. 短路逻辑 Python中进行逻辑运算的时候, 默认采用的是一种叫做短路逻辑的运算规则. 名字是很形象的, 下面直接 ...