zoukankan      html  css  js  c++  java
  • 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);
        }
    })
  • 相关阅读:
    Proj THUDBFuzz Paper Reading: The Art, Science, and Engineering of Fuzzing: A Survey
    Proj THUDBFuzz Paper Reading: A systematic review of fuzzing based on machine learning techniques
    9.3 付费代理的使用
    11.1 Charles 的使用
    第十一章 APP 的爬取
    10.2 Cookies 池的搭建
    10.1 模拟登录并爬取 GitHub
    11.5 Appium 爬取微信朋友圈
    11.4 Appium 的基本使用
    11.3 mitmdump 爬取 “得到” App 电子书信息
  • 原文地址:https://www.cnblogs.com/TiestoRay/p/5032202.html
Copyright © 2011-2022 走看看