ASP.NET Core API POST 参数始终为空
Posted
技术标签:
【中文标题】ASP.NET Core API POST 参数始终为空【英文标题】:ASP.NET Core API POST parameter is always null 【发布时间】:2017-06-07 12:25:59 【问题描述】:我已阅读以下内容:
Asp.net Core Post parameter is always null asp.net webapi 2 post parameter is always null web-api POST body object always null Web Api Parameter always null我的端点:
[HttpPost]
[Route("/getter/validatecookie")]
public async Task<IActionResult> GetRankings([FromBody] string cookie)
int world = 5;
ApiGetter getter = new ApiGetter(_config, cookie);
if (!await IsValidCookie(getter, world))
return BadRequest("Invalid CotG Session");
HttpContext.Session.SetString("cotgCookie", cookie);
return Ok();
我的要求:
$http.post(ENDPOINTS["Validate Cookie"], cookie , 'Content-Type': 'application/json');
cookie
是我从用户输入发送的字符串。
请求使用适当的数据发布到端点。但是,我的字符串始终为空。我尝试删除[FromBody]
标签,并在发布的数据前添加=
,但没有成功。我还尝试使用上述所有组合添加和删除不同的内容类型。
我做这个具体动作的原因很长,和这个问题无关。
为什么无论我做什么,我的参数总是为空?
编辑:我也尝试过使用cookie: cookie
Edit2:请求:
Request URL:http://localhost:54093/getter/validatecookie
Request Method:POST
Status Code:400 Bad Request
Remote Address:[::1]:54093
响应标头
Content-Type:text/plain; charset=utf-8
Date:Mon, 23 Jan 2017 03:12:54 GMT
Server:Kestrel
Transfer-Encoding:chunked
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?QzpcVXNlcnNcRG91Z2xhc2cxNGJcRG9jdW1lbnRzXFByb2dyYW1taW5nXENvdEdcQ290RyBBcHBcc3JjXENvdEdcZ2V0dGVyXHZhbGlkYXRlY29va2ll?=
请求标头
POST /getter/validatecookie HTTP/1.1
Host: localhost:54093
Connection: keep-alive
Content-Length: 221
Accept: application/json, text/plain, */*
Origin: http://localhost:54093
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/55.0.2883.87 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: http://localhost:54093/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8
请求负载
=sec_session_id=[redacted]; _ga=[redacted]; AWSELB=[redacted]
【问题讨论】:
您是否使用过 Fiddler 或浏览器的网络控制台等工具来确保 POST 正确发送正文? @ShaunLuttin 是的,我提到它确实发布了适当的数据。数据在请求中发送。 您可以发布实际的 HTTP 请求及其标头和正文,而不是发布您如何发出 AJAX 请求。这可能有助于解决问题。 @ShaunLuttin 我已经在里面添加了请求 您的请求负载不是 JSON,而您的 Content-Type 是 application/json。 【参考方案1】:问题在于Content-Type
是application/json
,而请求负载实际上是text/plain
。这将导致 415 Unsupported Media Type HTTP 错误。
您至少有两个选项可以对齐Content-Type
和实际内容。
使用应用程序/json
将Content-Type
保留为application/json
,并确保请求有效负载是有效的 JSON。例如,使您的请求有效负载:
"cookie": "=sec_session_id=[redacted]; _ga=[redacted]; AWSELB=[redacted]"
那么动作签名需要接受一个与JSON对象形状相同的对象。
public class CookieWrapper
public string Cookie get; set;
而不是 CookieWrapper
类,或者您可以接受动态,或 Dictionary<string, string>
并像端点中的 cookie["cookie"]
一样访问它
public IActionResult GetRankings([FromBody] CookieWrapper cookie)
public IActionResult GetRankings([FromBody] dynamic cookie)
public IActionResult GetRankings([FromBody] Dictionary<string, string> cookie)
使用文本/纯文本
另一种选择是将您的Content-Type
更改为text/plain
并将纯文本输入格式化程序添加到您的项目中。为此,请创建以下类。
public class TextPlainInputFormatter : TextInputFormatter
public TextPlainInputFormatter()
SupportedMediaTypes.Add("text/plain");
SupportedEncodings.Add(UTF8EncodingWithoutBOM);
SupportedEncodings.Add(UTF16EncodingLittleEndian);
protected override bool CanReadType(Type type)
return type == typeof(string);
public override async Task<InputFormatterResult> ReadRequestBodyAsync(
InputFormatterContext context,
Encoding encoding)
string data = null;
using (var streamReader = context.ReaderFactory(
context.HttpContext.Request.Body,
encoding))
data = await streamReader.ReadToEndAsync();
return InputFormatterResult.Success(data);
并配置 Mvc 来使用它。
services.AddMvc(options =>
options.InputFormatters.Add(new TextPlainInputFormatter());
);
另见
https://github.com/aspnet/Mvc/issues/5137
【讨论】:
感谢回复,刚刚试过,同样的交易。 ASP.NET 参数是否不像其他框架那样接受数据? 知道了... ASP.NET Core 不支持将text/plain
作为开箱即用的Content-Type
。
Shaun,我最终将Dictionary<string,string>
与"cookie":cookie
对象一起使用。然后我在我的端点中像cookie["cookie"]
一样访问它。如果您可以将其添加为潜在的解决方案之一,我将接受您的回答。
这不应该是答案。您可以在 .Net Core 中非常轻松地发送字符串,而无需所有这些棘手的操作。请参阅下面的答案
您可以看到他是从Microsoft.AspNetCore.Mvc.Formatters
中的TextInputFormatter
派生的。然而,这是一个抽象类,此时唯一的派生类是 JSON 和 XML。也就是说,我真的希望 TextPlainInputFormatter
被包括在内。非常感谢,肖恩!【参考方案2】:
您只需将正文放在引号中,使其代表string
。您还需要将请求类型保留为application/json
。这样媒体类型格式化程序就会弄清楚:
"=sec_session_id=[redacted]; _ga=[redacted]; AWSELB=[redacted]"
应该做的伎俩。
【讨论】:
变量cookie
已经是一个字符串,它作为字符串在JS中传递。
对,但是请求负载也需要用双引号字符封装,以便媒体类型格式化程序正确处理[FromBody]
属性。【参考方案3】:
Shaun Luttin 的回答有效,但它遗漏了一条重要信息。无法识别您的字符串的原因是它不是 JSON 字符串。
这样做;
var payload=JSON.stringify("=sec_session_id=[redacted]; _ga=[redacted]; AWSELB=[redacted]");
然后你可以让控制器保持原样;
$.ajax(
url: http://localhost:54093/getter/validatecookie,
type: 'POST',
contentType: 'application/json',
data: payload
);
令人尴尬的是,我花了多长时间才弄清楚。我真的希望它可以帮助别人!
【讨论】:
工作。使用 axios 发布 payload【参考方案4】:可笑的是, 在 dot net core 中,您不能只使用“frombody 字符串参数”。 你应该为一个字符串参数创建一个模型类。
public async Task<IActionResult> GetRankings([FromBody] string cookie)
=>
//1. make a model. MyCookie.cs
class MyCookie
public string Cookie get; set;
//2. edit your parameter
public async Task<IActionResult> GetRankings([FromBody] MyCookie cookie)
【讨论】:
【参考方案5】:我需要通过 .Net 桌面客户端将字符串数据发布到 .NET Core 主机。我收到不支持的媒体错误。我遵循了 Shaun Luttin 的回答并且工作正常。我发现了一些更容易获取字符串数据的方法,以防其他人发现有用:
[HttpPost]
[Route("Request/Echo")]
public async Task<string> Echo()
using (var Reader = new StreamReader(Request.Body, Encoding.UTF8))
return await Reader.ReadToEndAsync();
This post 很有用。
【讨论】:
【参考方案6】:我为此苦苦挣扎了很久,最后,在查看了 DevExpress 控件为“PUT”到 Razor 页面所做的工作之后,我发现了这个问题:
$.ajax(
type: "PUT",
url: "/GoalGrid?handler=Single",
dataType: "json",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
data: values: single
)
GoalGrid.cshtml.cs
public JsonResult OnPutSingle(string values)
// Do stuff with 'values' here
诀窍是使用“application/x-www-form-urlencoded; charset=UTF-8”作为请求的 contentType。这样您就不需要为单个字符串值创建一个类。一切都按预期进行。
【讨论】:
【参考方案7】:我的特殊问题是模型绑定对于 JSON 模型静默失败。 (它始终为空)。
由于我发布了确切的 JSON,我能够通过在本地运行 Web 服务在本地调试它,并通过 cURL 发布到我的控制器(可以使用 POSTMAN)。
使用下面的代码,我能够看到序列化过程中发生的确切异常。
[HttpPost]
public IActionResult MyAction([FromBody] dynamic request)
if (request != null)
try
var objAttempt =
JsonConvert.DeserializeObject<MyModel>(
JsonConvert.SerializeObject(request));
catch (Exception exception)
Console.WriteLine(exception);
throw;
【讨论】:
【参考方案8】:对我来说,只需将[FromBody]
添加到参数列表即可解决问题。
希望这可以节省别人的时间。
【讨论】:
【参考方案9】:就我而言,我按照@guhyeon 的建议进行了设置,模型类只包含一个字符串属性。除了,它没有被定义为属性,它只是
public class PdfInfoRequestDto
public string PdfInBase64;
由于某种原因,这适用于 .net 框架 4.7.2 webapi,我可以从请求正文中收到我需要的值。但是当我尝试在 .net core 3.1 webapi 中使用相同的请求、模型和所有内容复制相同内容时,PdfInBase64 中的值总是以 null 的形式到达我的控制器。将字段更改为属性后:
public string PdfInBase64 get; set;
我开始正确获取请求正文中传递的值。
【讨论】:
【参考方案10】:在两个参数上使用 [FromForm] 为我修复了它。如:
[HttpPost]
public IActionResult Insrtmyinfo([FromForm] string firstparam, [FromForm] string secndparam)
...
【讨论】:
以上是关于ASP.NET Core API POST 参数始终为空的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core Web API HTTP POST 在 Azure 中返回 404
详解ASP.NET Core API 的Get和Post请求使用方式