C# webapi post方法参数值为null
webapi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class ValuesController : ApiController { // GET api/values public IEnumerable< string > Get() { return new string [] { "value1" , "value2" }; } // GET api/values/5 public string Get( int id) { return "value" ; } [HttpPost] // POST api/values public void Post([FromBody] string value) { XTrace.WriteLine( "values:" +value); } // PUT api/values/5 public void Put( int id, [FromBody] string value) { } // DELETE api/values/5 public void Delete( int id) { } } |
(1)表单提交方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <html> <head> <title>测试表单</title> </head> <body> <form id= "myForm" action= "/api/values" method= "post" > <input type= "text" value= "hhh" placeholder= "请输入你的名字" /> <input type= "submit" value= "提交" /> <!--<input type= "submit" value= "提交" />--> </form> <script> //var form = document.getElementById("myForm"); </script> </body> </html> |
后台无法获取到value的值,一直为null。将[FromBody]属性修改为[FromUri]即可以获取到参数的值,默认form提交表单是通过url传参的,详细了解了解一下webapi的Frombody和FromUri做了什么工作,以及ajax提交方式,怎样写是对应着body,怎样写是对应着uri。
(2)使用Fiddler发起post请求
webapi 属性设置为[FromBody],设置Content-Type为application/json,在RequestBody中输入键值对,可以成功post并获取到对象。若不设置Content-Type,但设置RequestBody,http返回415错误。
1 2 3 4 | public void Post([FromBody] string value) { XTrace.WriteLine( "values:" +value); } |
webapi属性设置为[FromUri],通过url中传入参数值post可以成功获取到.
1 2 3 4 | public void Post([FromUri] string value) { XTrace.WriteLine( "values:" +value); } |
由此,可以推测出html中使用form提交表单时,在属性为[FromBody]时,要成功访问参数,需要设置content-type格式。问题是,使用form标签时,只能设置encrypt属性(提交数据的格式),
1 application/x-www-form-urlencoded: 概述: 当action为get,数据被编码为名称/值对,是标准的编码格式,也是默认的编码格式 格式:name1=value1&name2&value2 把form数据转换成一个字串,然后把这个字串append到url后面,用?分割,加载这个新的url
2 multipart/form-data: 概述:当action为post时,浏览器把form数据封装到http body中,然后发送到server。 如果没有type=file的控件,用默认的application/x-www-form-urlencoded就可以了。 但是如果有type=file的话,就要用到multipart/form-data了。浏览器会把整个表单以控件为单位分割,并为每个部分加上ContentDisposition(form-data或者file),Content-Type(默认为text/plain),name(控件name)等信息,并加上分割符(boundary)。file或者img等发生上传文件时,设置entype = 'multipart/form-data',是上传二进制数据,它告诉我们传输的数据要用到多媒体传输协议,由于多媒体传输的都是大量的数据,所以规定上传文件必须是post方法,<input>的type属性必须是file。form里面的input的值以2进制的方式传过去,所以request就得不到值了。
可以看到,可以通过multipart/form-data的方式封装数据到http body中,然后后台进行解析,问题是默认的Content-Type是text/plain,而不是application/json。存疑:不能通过form标签指定Content-Type为application/json,只能通过ajax指定?。顺理成章地,应该可以提交ajax请求,指定Content-Type为application/json来获取数据。奇怪的是,这种ajax提交方式获取不到参数值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <html> <head> <title>测试表单</title> </head> <body> <form> <button type= "button" id= "submit" >提交</button> </form> <script> var button = document.getElementById( "submit" ); button.onclick = function () { $.ajax({ url: "/api/values" , method: "post" , contentType: "application/json" , dataType: "json" , data: JSON.stringify( "hhh" ), }); } </script> </body> </html> |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· Qt个人项目总结 —— MySQL数据库查询与断言