当我将一个字符串发布到ASP.Net Core时,它与其他许多字符串(例如36个答案here)一样始终为null。我尝试了[FromBody]
,但是这导致我的电话收到400错误。最终,我找到了这个“解决方案”,该方法有效:
[Route("api/[controller]")]
[ApiController]
public class ScoresController : ControllerBase
{
[HttpPost]
public void Post(string value)
{
# 'value' is null, so ...
Request.EnableRewind();
var body = "";
using (var reader = new StreamReader(Request.Body))
{
Request.Body.Seek(0, SeekOrigin.Begin);
body = reader.ReadToEnd();
}
value = body;
# Now 'value' is correct, use it ...
}
}
以下是我从客户端(Python,使用“ requests”)发布的值的示例:
'{“用户名”:“ TestUserNumber5”,“电子邮件”:“ testuser5@nowhere.com”,“密码哈希”:5}'
一旦我从ASP.Net Core的正文中检索到它,它就会像这样:
“ {\”用户名\“:\” TestUserNumber5 \“,\”电子邮件\“:\” testuser5@nowhere.com \“,\” PasswordHash \“:5}”
我没有明确设置内容类型,这是我用来发布的Python代码:
def add_score(score):
score_json = json.dumps(score)
response = requests.post(url+"scores/", data=score_json, verify=False)
return response.ok
第二遍阅读尸体似乎很不客气。我为什么需要它?
答案 0 :(得分:0)
一些关键信息被排除在外:即,这是否是API样式的控制器,是否使用[ApiController]
属性以及如何正在发布信息(x-www-form-urlencoded
,application/json
,text/plain
等。不过,我会根据您的行为做出一些假设。
如果我不得不猜测,我会说这是一个API样式的控制器,并且您已应用了[ApiController]
属性。默认情况下,这会将绑定切换到[FromBody]
,但仅在类类型上,而不在诸如字符串之类的基本类型上。因此,默认情况下,字符串参数通常被忽略。当您将[FromBody]
属性显式应用到参数时,您将强制将请求主体绑定到该参数,而发送的内容将无法被发送(因此出现400 Bad Request)。
因此,我们可以了解您发布的内容。您很有可能发送application/json
作为内容类型,但您的请求正文仅为my string value
。那不是有效的JSON,您得到400。如果您只想将字符串作为JSON发送,则它必须是 JSON字符串,这基本上意味着它需要用引号引起来: "my string value"
。您仍然需要将[FromBody]
属性显式应用到该参数,但是如果添加引号,它将通过。
更新
这就是为什么代码对问题如此重要的原因。看起来您是作为字符串从客户端发送的,然后将其绑定到ASP.NET Core应用程序中的字符串。但是,实际数据本身是JSON。
问题在于,对于像string
这样的基本类型,默认绑定将是FromForm
。但是,您没有发送x-www-form-urlencoded
请求。添加[FromBody]
也不起作用,因为即使看上去看起来像JSON,它也不会以JSON内容类型发送。实际上,您的内容类型很可能是text/plain
,并且ASP.NET Core默认没有应用text/plain
输入格式化程序。您可以更改,但这确实不理想。
简单地说,您有一个要通过HTTP传输到API的对象。这意味着您应该使用一种对象友好的格式,例如JSON或XML。在Python方面,将您的请求发送为实际JSON,而不是包含序列化JSON对象的字符串。在ASP.NET Core端,创建一个具有该JSON对象成员属性的类,并将其用作您的参数。这样,您将没有问题。