热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于HttpClient用Post方式调用webapi传实体参数的问题

同一个action我在网页上写JS用ajax就可以调用成功了但是用C#中的HttpClient对象调用的时候不管怎么弄webapi那边都接收不到实体参数每次获取到的都是null只有把we
同一个action 我在网页上写JS 用ajax就可以调用成功了 但是用C#中的HttpClient对象调用的时候 不管怎么弄 webapi那边都接收不到实体参数 每次获取到的都是null 只有把webapi那边接收参数类型改为Json类库中的JObject类型才可以接收得到(如果改成Object类型就只是接收到一个什么属性字段都没有的对象)
我就是想问怎么样可以像JS那样让webapi直接接收到我想要的实体参数?

16 个解决方案

#1


如果凭的经验无法使两边发送的请求参数达成格式一致,那么你可以选择使用截包工具,把两边发送的数据做一下比对,找到其中的差异

#2


引用 1 楼 xdashewan 的回复:
如果凭的经验无法使两边发送的请求参数达成格式一致,那么你可以选择使用截包工具,把两边发送的数据做一下比对,找到其中的差异

我用google浏览器查看ajax请求的Request Header 然后我把HttpClient发送的请求头基本都改成和他一样的了 但还是不行

#3


引用 2 楼 Brown_Sugar 的回复:
我用google浏览器查看ajax请求的Request Header 然后我把HttpClient发送的请求头基本都改成和他一样的了 但还是不行

参数是请求体而不是请求头

#4


也许和请求头的内容类型有关系 ,WEBAPI接收POST来的参数时,可以建一个实体类作参数类型放在方法参数上

 request.ContentType = "application/x-www-form-urlencoded" // "表单"形式
                                        "application/json";
                                        "text/xml";

#5


http://blog.csdn.net/hanjun0612/article/details/60126445

#6


引用 5 楼 hanjun0612 的回复:
http://blog.csdn.net/hanjun0612/article/details/60126445

你给的这个代码跟我百度查到的基本相同 我就是这么写的 实体参数还是不能直接接收到

#7


引用 3 楼 xdashewan 的回复:
是请求体而不是请求头

请求体是一样的 我调试webapi 用 HttpContext.Current.Request.Form.ToString() 获取请求体字符串 然后我对比用JS中ajax请求和用C#中HttpClient对象发送的请求体 是一样的 但是偏偏用HttpClient对象发送的时候实体参数就是null

#8


传递JSON字符串即可!!!!!!!!

#9


引用 6 楼 Brown_Sugar 的回复:
Quote: 引用 5 楼 hanjun0612 的回复:

http://blog.csdn.net/hanjun0612/article/details/60126445

你给的这个代码跟我百度查到的基本相同 我就是这么写的 实体参数还是不能直接接收到

你自己测试一下把。没问题的
public class TestController : ApiController
    {
//发起请求
        [HttpGet]
        public async Task Get()
        {//调用请求方法
            var q = await APIPost("http://localhost:16727/api/Test/Post","{'name':'Hello','age':17}");
//post api的返回数据
            return q;
        }
//被请求的post api
        [HttpPost]
        public string Post(User data)
        {

            return "123";
        }

//传递对象
public class User
{
    public string name{get;set;}
    public int age{get;set;}
}

        public static async Task APIPost(string url, string data)
        {
            string result = string.Empty;
            //设置HttpClientHandler的AutomaticDecompression  
            var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };
            //创建HttpClient(注意传入HttpClientHandler)  
            using (var http = new HttpClient(handler))
            {
                //使用FormUrlEncodedContent做HttpContent  
                var content = new FormUrlEncodedContent(new Dictionary()         
                {  
                  {"", data}//键名必须为空  
                 });

                //await异步等待回应  
                var response = await http.PostAsync(url, content);
                //确保HTTP成功状态值  
                response.EnsureSuccessStatusCode();
                //await异步读取最后的JSON(注意此时gzip已经被自动解压缩了,因为上面的AutomaticDecompression = DecompressionMethods.GZip)  
                result = await response.Content.ReadAsStringAsync();
            }
            return result;
        }  
    }

#10


引用 9 楼 hanjun0612 的回复:
你自己测试一下把。没问题的
public class TestController : ApiController
    {
//发起请求
        [HttpGet]
        public async Task Get()
        {//调用请求方法
            var q = await APIPost("http://localhost:16727/api/Test/Post","{'name':'Hello','age':17}");
//post api的返回数据
            return q;
        }
//被请求的post api
        [HttpPost]
        public string Post(User data)
        {

            return "123";
        }

//传递对象
public class User
{
    public string name{get;set;}
    public int age{get;set;}
}

        public static async Task APIPost(string url, string data)
        {
            string result = string.Empty;
            //设置HttpClientHandler的AutomaticDecompression  
            var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };
            //创建HttpClient(注意传入HttpClientHandler)  
            using (var http = new HttpClient(handler))
            {
                //使用FormUrlEncodedContent做HttpContent  
                var content = new FormUrlEncodedContent(new Dictionary()         
                {  
                  {"", data}//键名必须为空  
                 });

                //await异步等待回应  
                var response = await http.PostAsync(url, content);
                //确保HTTP成功状态值  
                response.EnsureSuccessStatusCode();
                //await异步读取最后的JSON(注意此时gzip已经被自动解压缩了,因为上面的AutomaticDecompression = DecompressionMethods.GZip)  
                result = await response.Content.ReadAsStringAsync();
            }
            return result;
        }  
    }


我晕 我说的是我api接收不到实体参数 不是客户端接收不到返回值 
你在Post方法里面打断点看看参数data的值有吗 我刚才按照你这个参数格式写还是接收不到

#11


引用 4 楼 mirror030 的回复:
也许和请求头的内容类型有关系 ,WEBAPI接收POST来的参数时,可以建一个实体类作参数类型放在方法参数上

 request.ContentType = "application/x-www-form-urlencoded" // "表单"形式
                                        "application/json";
                                        "text/xml";


只是 "application/json" 而已。多了乱了才造成不会调试的问题。

#12


asp.net 各种不定性、各种抄袭 java 不兼容方式都乱了。其实你使用10几年前的 asp.net 技术可以非常方便地2、3行代码自己处理参数。

#13


引用 10 楼 Brown_Sugar 的回复:
我晕 我说的是我api接收不到实体参数 不是客户端接收不到返回值 
你在Post方法里面打断点看看参数data的值有吗 我刚才按照你这个参数格式写还是接收不到


传递对象的话,使用以下方式
                var content = new FormUrlEncodedContent(new Dictionary()         
                {  
                   {"name","hello"},
                     {"age","16"}

                 });

#14


引用 13 楼 hanjun0612 的回复:
传递对象的话,使用以下方式
                var content = new FormUrlEncodedContent(new Dictionary()         
                {  
                   {"name","hello"},
                     {"age","16"}

                 });


 终于发现问题所在了,我的实体参数类型中声明了一个 protected set 的属性,只要给他一个默认值或者去掉protected就没问题 应该是webapi本身在对实体参数赋值的过程中遇到没给默认值又没有权限赋值的属性会无法生成实体对象 结果收到的参数就是null 
之前怎么都没想到是这个问题

#15


还发现了个更坑爹的问题 如果你的实体参数类型是一个继承了父类并且用new关键字覆盖了父类的属性 而且子类的这个属性和父类的属性的类型不同 也会导致接收到的实体参数值为null 
比如以下这种情况:

public class BaseParameter
{
    public int Property { get; set; }
}

public class Parameter : BaseParameter
{
    public new Guid Property { get; set; }
}

#16


现在有个比较通用的解决方法 就是在请求头设置 Content-Type 为 application/json 然后传Json字符串过去 之前我所遇到的那些问题就都没有了

推荐阅读
author-avatar
郭建将_683
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有