繁体   English   中英

如何在 POST 请求中更好地处理无效 json 的错误?

[英]How to better error handling on invalid json, on POST request?

假设我在我的 .NET Core 3.1 网络应用程序中作为 api 在我的PotatoController上执行此操作:

[HttpPost]
    public async Task<IActionResult> CreatePotatoAsync([FromBody] Potato potato)
{
// Code to create potato
}

现在假设用户在尝试创建新土豆时,发送和无效的 json 如下所示:

{
"potatoName": "testPotato",
"potatoAge": 7,
}

什么是我的 api 从System.Text.Json库返回的不是丑陋的 500 错误的最佳方法,而是我创建的一个不错的自定义 400?

当我创建 a.Net 3.1 测试 API 项目并使用您发布的代码时,我得到的响应是带有此正文的 400 BadRequest 响应:

{
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "|57182e0e-445086f96bddb4e8.",
    "errors": {
        "$.potatoAge": [
            "The JSON object contains a trailing comma at the end which is not supported in this mode. Change the reader options. Path: $.potatoAge | LineNumber: 3 | BytePositionInLine: 0."
        ]
    }
}

当我取消[ApiController]属性时,我得到一个 null 土豆 object。 我无法复制您从 System.Text.Json 获得 500 的行为

因此,它似乎可以满足您开箱即用的需求。 您是否使用自定义 JSON 序列化程序或其他 model 绑定选项? 你能发布更多你的代码吗?

我更喜欢返回 200 并在应用程序级别处理错误

如果我不需要返回任何值

{
    "status": "ok"
}

如果我需要返回一个值

{
    "status": "ok",
    "result": [
        {
            "Name": "Fabio"
        },
        {
            "Name": "Laura"
        }
    ]
}

并且万一发生错误

{
    "status": "ko",
    "exceptionMessage": "Something went wrong!"
}

考虑在控制器的基础 class 中包含以下方法

/// <summary>
/// Processes the request using a method that does not return any value 
/// </summary>
/// <param name="action">The method to be used to process the request</param>
protected JsonResult ProcessRequest(Action action)
{
    return ProcessRequest(() =>
    {
        action();
        return null;
    });
}

/// <summary>
/// Processes the request using a method that returns a value 
/// </summary>
/// <param name="func">The method to be used to process the request</param>
protected JsonResult ProcessRequest(Func<object> func)
{
    JsonResult jsonResult = new JsonResult();

    try
    {
        object result = func();

        if (result != null)
        {
            jsonResult.Data = new { status = "ok", result = result, };
        }
        else
        {
            jsonResult.Data = new { status = "ok", };
        }
    }
    catch (Exception e)
    {
        string message = e.Message;
        jsonResult.Data = new { status = "ko", exceptionMessage = message, };
    }

    return jsonResult;
}

然后您的操作方法将如下所示

public ActionResult DoThat()
{
    return ProcessRequest(() =>
    {
        // Do something 
    });
}

public ActionResult ReturnPersonList()
{
    return ProcessRequest(() =>
    {
        return new List<Person> { new Person { Name = "Fabio" }, new Person { Name = "Laura" } };
    });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM