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

Brown_Sugar 2017-08-17 10:09:24
同一个action 我在网页上写JS 用ajax就可以调用成功了 但是用C#中的HttpClient对象调用的时候 不管怎么弄 webapi那边都接收不到实体参数 每次获取到的都是null 只有把webapi那边接收参数类型改为Json类库中的JObject类型才可以接收得到(如果改成Object类型就只是接收到一个什么属性字段都没有的对象)
我就是想问怎么样可以像JS那样让webapi直接接收到我想要的实体参数?
...全文
1135 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
正怒月神 版主 2017-08-21
  • 打赏
  • 举报
回复
引用 10 楼 Brown_Sugar 的回复:
我晕 我说的是我api接收不到实体参数 不是客户端接收不到返回值 你在Post方法里面打断点看看参数data的值有吗 我刚才按照你这个参数格式写还是接收不到
传递对象的话,使用以下方式 var content = new FormUrlEncodedContent(new Dictionary<string, string>() { {"name","hello"}, {"age","16"} });
Brown_Sugar 2017-08-21
  • 打赏
  • 举报
回复
现在有个比较通用的解决方法 就是在请求头设置 Content-Type 为 application/json 然后传Json字符串过去 之前我所遇到的那些问题就都没有了
Brown_Sugar 2017-08-21
  • 打赏
  • 举报
回复
还发现了个更坑爹的问题 如果你的实体参数类型是一个继承了父类并且用new关键字覆盖了父类的属性 而且子类的这个属性和父类的属性的类型不同 也会导致接收到的实体参数值为null 比如以下这种情况:

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

public class Parameter : BaseParameter
{
    public new Guid Property { get; set; }
}
Brown_Sugar 2017-08-21
  • 打赏
  • 举报
回复
引用 13 楼 hanjun0612 的回复:
传递对象的话,使用以下方式 var content = new FormUrlEncodedContent(new Dictionary<string, string>() { {"name","hello"}, {"age","16"} });
终于发现问题所在了,我的实体参数类型中声明了一个 protected set 的属性,只要给他一个默认值或者去掉protected就没问题 应该是webapi本身在对实体参数赋值的过程中遇到没给默认值又没有权限赋值的属性会无法生成实体对象 结果收到的参数就是null 之前怎么都没想到是这个问题
  • 打赏
  • 举报
回复
asp.net 各种不定性、各种抄袭 java 不兼容方式都乱了。其实你使用10几年前的 asp.net 技术可以非常方便地2、3行代码自己处理参数。
  • 打赏
  • 举报
回复
引用 4 楼 mirror030 的回复:
也许和请求头的内容类型有关系 ,WEBAPI接收POST来的参数时,可以建一个实体类作参数类型放在方法参数上 request.ContentType = "application/x-www-form-urlencoded" // "表单"形式 "application/json"; "text/xml";
只是 "application/json" 而已。多了乱了才造成不会调试的问题。
xdashewan 2017-08-18
  • 打赏
  • 举报
回复
如果凭的经验无法使两边发送的请求参数达成格式一致,那么你可以选择使用截包工具,把两边发送的数据做一下比对,找到其中的差异
Brown_Sugar 2017-08-18
  • 打赏
  • 举报
回复
引用 9 楼 hanjun0612 的回复:
你自己测试一下把。没问题的
public class TestController : ApiController
    {
//发起请求
        [HttpGet]
        public async Task<string> 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<string> 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<string, string>()         
                {  
                  {"", 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的值有吗 我刚才按照你这个参数格式写还是接收不到
正怒月神 版主 2017-08-18
  • 打赏
  • 举报
回复
引用 6 楼 Brown_Sugar 的回复:
[quote=引用 5 楼 hanjun0612 的回复:]
http://blog.csdn.net/hanjun0612/article/details/60126445

你给的这个代码跟我百度查到的基本相同 我就是这么写的 实体参数还是不能直接接收到[/quote]
你自己测试一下把。没问题的
public class TestController : ApiController
{
//发起请求
[HttpGet]
public async Task<string> 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<string> 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<string, string>()
{
{"", 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;
}
}

Im_Sorry 2017-08-18
  • 打赏
  • 举报
回复
传递JSON字符串即可!!!!!!!!
Brown_Sugar 2017-08-18
  • 打赏
  • 举报
回复
引用 3 楼 xdashewan 的回复:
是请求体而不是请求头
请求体是一样的 我调试webapi 用 HttpContext.Current.Request.Form.ToString() 获取请求体字符串 然后我对比用JS中ajax请求和用C#中HttpClient对象发送的请求体 是一样的 但是偏偏用HttpClient对象发送的时候实体参数就是null
Brown_Sugar 2017-08-18
  • 打赏
  • 举报
回复
引用 5 楼 hanjun0612 的回复:
http://blog.csdn.net/hanjun0612/article/details/60126445
你给的这个代码跟我百度查到的基本相同 我就是这么写的 实体参数还是不能直接接收到
正怒月神 版主 2017-08-18
  • 打赏
  • 举报
回复
http://blog.csdn.net/hanjun0612/article/details/60126445
mirrorspace 2017-08-18
  • 打赏
  • 举报
回复
也许和请求头的内容类型有关系 ,WEBAPI接收POST来的参数时,可以建一个实体类作参数类型放在方法参数上 request.ContentType = "application/x-www-form-urlencoded" // "表单"形式 "application/json"; "text/xml";
xdashewan 2017-08-18
  • 打赏
  • 举报
回复
引用 2 楼 Brown_Sugar 的回复:
我用google浏览器查看ajax请求的Request Header 然后我把HttpClient发送的请求头基本都改成和他一样的了 但还是不行
参数是请求体而不是请求头
Brown_Sugar 2017-08-18
  • 打赏
  • 举报
回复
引用 1 楼 xdashewan 的回复:
如果凭的经验无法使两边发送的请求参数达成格式一致,那么你可以选择使用截包工具,把两边发送的数据做一下比对,找到其中的差异
我用google浏览器查看ajax请求的Request Header 然后我把HttpClient发送的请求头基本都改成和他一样的了 但还是不行

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧