【问题标题】:Asp.net core 2.0 POST endpoint works without json payload, but fails (400 Bad request) with a json payloadAsp.net core 2.0 POST 端点在没有 json 有效负载的情况下工作,但使用 json 有效负载失败(400 Bad request)
【发布时间】:2018-04-09 15:17:15
【问题描述】:

我的 asp.net core 2.0 应用程序中有以下端点:

[HttpPost("postself")]
public IActionResult post([FromBody]JObject email)
{
    try
    {
        var service = new EmailService();
        var emailHtml = service.GenerateEmail(email.ToString(), false);
        return Json(new { Email = emailHtml });
    }
    catch
    {
        return Json(new { Email = "error" });
    }
}

这样调用 API 时:

curl -X POST \
  http://myapp/api/v1/emails/postself \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'postman-token: 85c9bbe7-2112-0746-5f41-8dc01b52ab59'

端点被命中并返回return Jason(new { Email = "error" });,这样就可以了。它返回error,因为JObjectnull,但这仍然是预期的行为。

但是,当这样调用 API 时(使用 JSON 有效负载):

curl -X POST \
  http://myapp/api/v1/emails/postself \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -H 'postman-token: a80c85de-8939-01d8-4a5d-c2108bf1491d' \
  -d '{
  "body": [
    {
      "image": {
        "url": "mailing_logo_slice.png",
        "alt": "This is my logo"
      }
    }
  ]
}'

...我的应用返回400 Bad request

此外,请求在开发中有效,但在生产中仅返回 400

有什么想法吗?

=========

更新代码:

[HttpPost("postself")]
public IActionResult PostSameDomain([FromBody]string email)
{
    try
    {
        var service = new EmailGenerationService();
        var emailHtml = service.GenerateEmailFromJson(email, false);
        return Json(new { Email = emailHtml });
    }
    catch
    {
        return Json(new { Email = "error" });
    }
}

[HttpPost("test")]
        public IActionResult PostSameDomain([FromBody]EmailViewModel email)
        {
            try
            {
                var service = new EmailGenerationService();
                var emailHtml = service.GenerateEmailFromJson(email.Raw, false);
                return Json(new { Email = emailHtml });
            }
            catch
            {
                return Json(new { Email = "error" });
            }
        }

【问题讨论】:

  • 您是否调试并查看了ModelState.IsValid + 它的各种其他属性?
  • 另外,您可能希望以“正确的方式”做事并使用实际的模型类。参见例如app.quicktype.io 根据您的输入 JSON 生成示例代码。
  • 对于您的 CURL 数据属性,-d '{"username":"abc","password":"abc"}' 有效吗?如果您没有得到 400,那么我认为这与请求中当前 JSON 对象的结构有关。
  • 确保您的 FromBody 参数可以反序列化 stackoverflow.com/a/46196415/804385 也使用 catch (Exception ex) 查看错误详细信息 - ex.Message 还要检查生产中的 Newtonsoft.Json.dll 是否没有遗漏
  • @PeterB 我在开发中检查了 ModelState。一切似乎都很好。关于您以“正确方式”做事的建议,因为每次我无法定义 POCO 时,发布的 json 的格式/模型都会有所不同。我只需要原始字符串或 JObject。我从 JObject 参数切换到纯字符串。在开发中这像以前一样工作,但在生产中仍然返回 400...还有其他想法吗?

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


【解决方案1】:

JObject 特定于 Newtonsoft.Json 并且不起作用。请指定包含 urlalt 属性的 POCO 类。

【讨论】:

    【解决方案2】:

    我相信您的问题是您正在传递一个 JSON 数组并试图将其反序列化为单个 JObject

    可能的修复:

    1. 传入单个 JSON 对象:

      curl -X POST \
        http://myapp/api/v1/emails/postself \
        -H 'cache-control: no-cache' \
        -H 'content-type: application/json' \
        -H 'postman-token: a80c85de-8939-01d8-4a5d-c2108bf1491d' \
        -d '{
        "body": {
            "image": {
              "url": "mailing_logo_slice.png",
              "alt": "This is my logo"
            }
          }
      }'
      
    2. 切换到JArray而不是JObject

      [HttpPost("postself")]
      public IActionResult post([FromBody]JArray email)
      {
          try
          {
              var service = new EmailService();
              var emailHtml = service.GenerateEmail(email.ToString(), false);
              return Json(new { Email = emailHtml });
          }
          catch
          {
              return Json(new { Email = "error" });
          }
      }
      
    3. 将数据作为string 接收并在其中反序列化。这将允许您测试您是否收到了一个数组或单个对象,然后根据需要反序列化为 JObjectJArray(这是我个人的建议)。

      李>

    【讨论】:

    • 我尝试了选项 3。这在开发中有效,但在生产中仍然返回 400。请参阅更新的问题。
    • 我还应该补充一点,常规表单帖子(因此来自实际的 html 表单)也以 400 失败。
    • HTML 表单将POST 使用application/x-www-form-urlencoded,而不是application/json。您不能对 form-urlencoded 数据使用 JSON 反序列化器。
    【解决方案3】:

    对于遇到此问题的其他人来说,this 是问题的根源。

    感谢大家一起思考我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多