事件回放:

之前一段时间,公司里前端用的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 后台无法获取参数的解决方案的更多相关文章

  1. springMVC --@RequestParam注解(后台控制器获取参数)

    在SpringMVC后台控制层获取参数的方式主要有两种,一种是request.getParameter("name"),另外一种是用注解@RequestParam直接获取. 1.获 ...

  2. asp.net webapi 的Request如何获取参数

    public class BaseApiController : ApiController { private HttpRequestBase _request; /// 全局Requests对象 ...

  3. JSP基础知识➣获取参数和过滤器(四)

    JSP表单提交和参数获取 JSP表单提交的两种方式:post和get,通过这两种方式提交的参数到后台,获取参数的值主要由request来处理,获取值的方式有以下几种: getParameter():  ...

  4. SpringMVC控制器接收不了PUT提交的参数的解决方案

    摘要: SpringMVC控制器接收不了PUT提交的参数的解决方案 这次改造了下框架,把控制器的API全部REST化,不做不知道,SpringMVC的REST有各种坑让你去跳,顺利绕过它们花了我不少时 ...

  5. axios 发 post 请求,后端接收不到参数的解决方案

    问题场景 场景很简单,就是一个正常 axios post 请求: axios({ headers: { 'deviceCode': 'A95ZEF1-47B5-AC90BF3' }, method: ...

  6. axios 发 post 请求,后端接收不到参数的解决方案(转载)

    原文地址:https://www.cnblogs.com/yiyi17/p/9409249.html 问题场景 场景很简单,就是一个正常 axios post 请求: axios({ headers: ...

  7. Servlet生命周期以及获取参数

    1. 创建Servlet几种方式  1) 实现Servlet接口     控制Servlet的生命周期       构造器       init()       service()       des ...

  8. WebAPI下的如何实现参数绑定

    本文将概述在WebAPI方式下将如何将参数绑定到一个action方法,包括参数是如何被读取,一系列规则决定特定环境采用的那种绑定方式,文章最后将给出一些实际的例子. Parameter binding ...

  9. [一步一步MVC]第二回:还是ActionFilter,实现对业务逻辑的统一Authorize处理 OnActionExecuting内如何获取参数

    如何获取参数:http://www.cnblogs.com/anytao/archive/2009/04/23/anytao-mvc-02-actionauthorize.html 由问题引出 在AS ...

随机推荐

  1. 不要给<a>设置outline:none

    outline属性有什么作用 原文链接 a{outline:none} do not do it 当用户使用tab键进行链接切换时,该属性会在当前选中的链接(获得焦点)使用该属性,一般来说是虚线框 的 ...

  2. Sybase数据库,普通表修改分区表步骤

    本文目标:指导项目侧人员再遇到此类改动需求时可以自己参照更改.需求:Sybase数据库,普通表t_jingyu修改为按天分区的分区表. 1.sp_help查看t_jingyu的表结构,索引等信息 sp ...

  3. 彻底解决低端安卓手机touchend事件不触发(考虑scroll)

    本次移动端开发时遇见了安卓4.2系统不能触发touchend的问题,有以下需求. 1. 横滑轮播图 2.下拉刷新页面内容 3.body滚动条不能失效 开始在轮播图touchmove事件中阻止了浏览器默 ...

  4. c#知识点总结

    1.如果要使用自动属性的话,必须2个都是自动属性, 不允许出现一个自动,一个非自动的情况,否则会报错. 2.命名规则,最好用动词+名词 比如 Is+Member+Valid ,方法的首字母大写,变量的 ...

  5. AppCan学习笔记--数据存储及listview简单应用

    AppCan AppCan开发平台简介 AppCan是Hybrid App开发框架即混合开发框架,有官方提供底层功能使用API HTML5和JavaScript只是作为一种解析语言,真正调用的都是Na ...

  6. CSS魔法堂:"那不是bug,是你不懂我!" by inline-block

    前言  每当来个需要既要水平排版又要设置固定高宽时,我就会想起display:inline-block,还有为了支持IE5.5/6/7的hack*display:inline;*zoom:1;.然后发 ...

  7. sed命令使用详解归纳

    用法 sed [option] 'Address Command' yourfile e.g. sed -n '2,13p' lineuser #打印文件lineuser中第2~13行的内容,-n为o ...

  8. css毛玻璃效果

    毛玻璃其实就是磨砂玻璃,能够模糊的看清背后的风景,让人感觉有种朦胧美,让界面看上去有些层次感. 比如: 高大上啊,接下来肯定是眼馋手痒的过程... 当然,用ps搞一个全景毛玻璃背景毫无疑问是最省事的, ...

  9. [WCF编程]10.操作:请求/应答操作

    一.调用操作概述 WCF除了支持经典的服务端-客户端的请求/应答操作外,还提供了对其他操作类型的内建支持,包括:即发即弃的单向调用:允许服务将调用返回给客户端的双向回调:允许客户端或服务器处理大量负荷 ...

  10. 一个简单的MVC实例及故障排除

    Controller: public ActionResult Index() { string setting = "ApplicationServices"; var conn ...