正文是正确的,为什么post值是null

时间:2019-03-22 12:21:04

标签: asp.net-core

当我将一个字符串发布到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

第二遍阅读尸体似乎很不客气。我为什么需要它?

1 个答案:

答案 0 :(得分:0)

一些关键信息被排除在外:即,这是否是API样式的控制器,是否使用[ApiController]属性以及如何正在发布信息(x-www-form-urlencodedapplication/jsontext/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对象成员属性的类,并将其用作您的参数。这样,您将没有问题。