【问题标题】:ASP Core 2 empty POST requestASP Core 2 空 POST 请求
【发布时间】:2018-02-17 15:37:10
【问题描述】:

我有一个简单的 HTTP POST 请求,我将它发送到使用 Kestrel 在 localhost 中运行的 ASP Core 2 应用程序。接收到的数据始终为 null,除非我使用来自另一个 C# 应用程序的 PostAsJsonAsync

我发送的json 有这种形式:

{
  "_isValid": true,
  "_username": "test",
  "_guid": "f3f574eb-5710-43c5-a4ff-0b75866a72a7",
  "_dt": "2018-02-11T15:53:44.6161198Z",
  "_ms": "IsSelected"
  [...]
}

ASP 控制器有这种形式:

// POST: api/NativeClient
[HttpPost]
public async Task<IActionResult> Post([FromBody]string value)
{
   [...]

1.案例:使用PostAsJsonAsync 从另一个 C# 应用发送

在一种情况下,我通过另一个使用 PostAsJsonAsync 的单独 C# 应用程序成功发送请求,如下所示:

HttpClient client = new HttpClient();
client.BaseAddress = new System.Uri("http://localhost:51022/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var response = await client.PostAsJsonAsync("/api/NativeClient/", json);

控制器接收到调用并成功填充value

2。案例:使用 Postman 等外部 REST 客户端发送

在另一种情况下,我尝试通过另一个 REST 客户端发送请求,例如 Postman 或通过 REST client extension 的 Visual Studio Code:

POST http://localhost:51022/api/NativeClient/ HTTP/1.1
content-type: application/json; charset=utf-8

{
  "_isValid": true,
  "_username": "gnappo",
  "_guid": "f3f574eb-5710-43c5-a4ff-0b75866a72a7",
  "_dt": "2018-02-11T15:53:44.6161198Z",
  "_ms": "IsSelected"
  [...]
}

这里控制器接收到请求,但string value始终是null

我试过删除[FromBody]标签,检查请求头,检查正文中的json字符串(完全相同),以及下面参考中提到的其他内容,但没有任何效果。

我错过了什么?


其他测试尝试/参考

Value are always null when doing HTTP Post requests

Asp.net Core 2 API POST Objects are NULL?

Model binding JSON POSTs in ASP.NET Core

【问题讨论】:

    标签: c# json asp.net-core http-post


    【解决方案1】:

    您应该将JSON 反序列化为某个模型(类),因为我相信您无论如何都会在代码中的某处反序列化此字符串:

    public class YourModel
    {
        public bool _isValid { get; set; }
        public string _username { get; set; }
        public string _guid { get; set; }
        public DateTime _dt { get; set; }
        public string _ms { get; set; }
        // other properties from json
    }
    

    你的行动:

    [HttpPost]
    public async Task<IActionResult> Post([FromBody] YourModel value)
    

    关于您的应用:

    在您的应用中,您将json 作为参数传递给PostAsJsonAsync(),但您需要传递对象,它将被解析为JSON

    var response = await client.PostAsJsonAsync("/api/NativeClient/", yourObject);
    

    yourObject 是应解析为JSON 的类的实例。

    评论后:

    另外,尝试将您的应用代码更改为:

    HttpClient client = new HttpClient();
    client.BaseAddress = new System.Uri("http://localhost:51022/");
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
    var httpContent = new StringContent(json, Encoding.UTF8, "application/json");    
    var response = await client.PostAsync("/api/NativeClient/", httpContent);
    

    【讨论】:

    • 感谢您的回答。如果我这样做,我可以使用 Postman 并且 YourModel value 得到正确填充,但是 PostAsJsonAsync 不再工作:我收到 null。有什么想法吗?
    • @alexlomba87,你发同样的JSON吗?
    • 您使用PostAsync 代替PostAsJsonAsync 的建议奏效了。回顾一下,我更改了控制器的签名,包括 stringYourModel,然后将 HttpClient 方法 PostAsJsonAsync(json) 交换为 PostAsync(new StringContent(json, Encoding.UTF8, "application/json")。谢谢。您想详细说明为什么它最初不起作用?我认为在答案中进行解释会很有用。
    • @alexlomba87,查看编辑,PostAsJsonAsync() 现在应该可以工作了
    【解决方案2】:

    POST请求需要声明发送的数据是text/plain。使用带有HttpClient 的示例:

    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/plain"));
    

    这样,您的 API 将能够接收您的 JSON 作为 string 内容。

    如果您希望将内容反序列化为原始模型对象,则需要将此标头添加到您的请求中:

    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    

    并将您的控制器更改为:

    // POST: api/NativeClient
    [HttpPost]
    public async Task<IActionResult> Post([FromBody]yourClass class)
    {
       [...]
    

    JSON 对象发送到您的API

    var Content = new StringContent(json, Encoding.UTF8, "application/json");
    var response = await client.PostAsync("/api/NativeClient/", Content);
    

    PostAsJsonAsync 将 C# 对象作为输入;它在发送之前将其序列化为JSON 字符串。 相反,PostAsync 可以使用 JSON 字符串发送。

    查看此问答httpclient-not-supporting-postasjsonasync-method-c-sharp

    查看此链接了解更多信息:

    PostAsJsonAsync in C#

    PostAsync

    【讨论】:

    • 我已经在单独的 C# 应用程序中设置了 MediaTypeWithQualityHeaderValue("application/json")。但是,如果我更改Post([FromBody] YourClass classValue) 中的控制器API,则只有通过邮递员发送POST 请求才能获得classValue;如果我使用PostAsJsonAsync 然后classValue 再次结果null。有什么想法吗?
    • 我看到你也喜欢 @Roma 编辑建议我将我的 PostAsJsonAsync 换成 PostAsync,并更改我的控制器签名以使用我的 Model 类而不是 string。虽然您的答案都有效,但我很难理解为什么我的原始解决方案不适用于两种类型的 HTTP 调用。您要详细说明吗?非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2020-07-16
    • 2013-08-16
    • 1970-01-01
    • 2021-05-24
    相关资源
    最近更新 更多