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);
    }
})
时间: 2024-10-03 01:41:30

WebApi Post 后台无法获取参数的解决方案的相关文章

springMVC [email&#160;protected]注解(后台控制器获取参数)

在SpringMVC后台控制层获取参数的方式主要有两种,一种是request.getParameter("name"),另外一种是用注解@RequestParam直接获取. 1.获取提交的参数: @RequestMapping("testRequestParam") public String filesUpload(@RequestParam String inputStr, HttpServletRequest request) { System.out.pri

JavaScript获取后台C#变量以及调用后台方法 &amp;&amp; 获取请求的URL参数

一.当然我们可以在后台中获取参数的值,然后在前台js代码中获取变量的值,具体做法请参考下面JavaScript获取后台C#变量以及调用后台方法. 其实我们也可以直接在js中获取请求的参数的值,通过使用window.location.search可以获取到当前URL的?号开始的字符串,如前面的链接获取到的search为?id=001.再对获取的字符串进行处理,就可以获取到参数的值了. 复制代码 代码如下: 1 function getUrlParam(name) { 2 var reg = new

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

JSP表单提交和参数获取 JSP表单提交的两种方式:post和get,通过这两种方式提交的参数到后台,获取参数的值主要由request来处理,获取值的方式有以下几种: getParameter(): 使用 request.getParameter() 方法来获取表单参数的值. getParameterValues(): 获得如checkbox类(名字相同,但值有多个)的数据. 接收数组变量 ,如checkbox类型 getParameterNames():该方法可以取得所有变量的名称,该方法返回

springmvc后台控制层获取参数的方法

在SpringMVC后台控制层获取参数的方式主要有两种, 一种是request.getParameter("name"), 另外一种是用注解@RequestParam直接获取.这里主要讲这个注解 一.基本使用,获取提交的参数 后端代码: Java代码   @RequestMapping("testRequestParam") public String filesUpload(@RequestParam String inputStr, HttpServletReq

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

摘要: SpringMVC控制器接收不了PUT提交的参数的解决方案 这次改造了下框架,把控制器的API全部REST化,不做不知道,SpringMVC的REST有各种坑让你去跳,顺利绕过它们花了我不少时间,这次来提下SpringMVC的PUT提交参数为null的情况. 照常先贴出我的控制器代码,没什么特别的,就是打印出接受到的前台参数值: @RequestMapping(value = "/{id}", method = RequestMethod.PUT) @ResponseBody

Struts2--result页面跳转forward--get方式和post方式的获取参数

一.总体概述 这篇文章是写基于struts2(整合了ssh)的2个页面之间的跳转传参.突然这天想到,struts2的result有很多的type类型(跳转,重定向,...),于是就回忆起,跳转和重定向的不同(跳转地址栏不变,共享参数:重定向地址栏改变,不再共享参数).心里好奇,struts2里页面跳转的时候,get的方式提交时怎么再第二个页面获取参数的,post是怎么在第二个页面获取参数的.重定向又是怎么样的呢?真的抱歉,我今天花了一天时间,只弄清楚了页面跳转,关于页面重定向传参明天再搞.本来这

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

如何获取参数:http://www.cnblogs.com/anytao/archive/2009/04/23/anytao-mvc-02-actionauthorize.html 由问题引出 在ASP .NET MVC中,以友好的URL访问资源是MVC吸引眼球的特色之一,但是随之而来对于Authorize问题的处理变得令人令人头痛.例如假设我们有一个获取Book信息的Action,定义在BookController中: public class BookController : Control

Struts2获取参数的几种方式

Struts2由于是一个贴心的框架,所以获取参数这种体力活,就无需再通过原生的request来getParameter了,有如下几种方式进行获取 1.Action中属性驱动,必须提供与form表单name相同的后台属性get/set,这种方式适合数据量比较少的form表单提交 2.大数据量的form表单,这时一般对应后台的一个实体类,所以这时还在每个action写属性驱动,那就会代码冗余,这时可以定义一个对象来属性来进行参数接收,如User对象,只是前台传参数的时候,需要先写对象名再点对象下的属

asp页面表单提交在后台不能获取问题

今天碰到一个奇葩的问题,asp页面表单提交后,有一个文本框<input type="text" name="phone" id="phone" />在后台获取不了, 这个标签在form表单内,也有name属性,但是在后台就是获取不了这个标签的值,而其他的文本框.复选框都可以获取到,这可就奇怪了! 几经周折,终于找到了原因,原来我在提交表单的时候,name = "phone"这个标签此时在一个javascript事件