You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core自定义InputFormatter如何返回错误触发4xx HTTP响应?

自定义TextInputFormatter解析失败时返回4xx状态码的正确实践

摘要
当为application/x-ourformat类型实现的自定义TextInputFormatter无法解析请求内容时,需要返回HTTP 400(或415)状态码,但官方示例中返回FailureAsync()的方式只会让输入对象变为null,不会触发4xx响应。本文说明正确的实现方式及相关原理。

问题场景

我们基于TextInputFormatter开发了针对application/x-ourformat的自定义格式化程序,参考官方示例的错误处理逻辑:

public override async Task<InputFormatterResult> ReadRequestBodyAsync(
        InputFormatterContext context, Encoding effectiveEncoding)
{
    ...
    return await InputFormatterResult.SuccessAsync(contact);
}
catch
{
    logger.LogError("Read failed: nameLine = {nameLine}", nameLine);
    return await InputFormatterResult.FailureAsync();
}

但实际测试发现,这种处理不会返回HTTP 400响应,仅会将API的输入绑定对象设为null。目前找到两种能触发400响应的方式:

  • 在ReadRequestBodyAsync中直接抛出异常
  • 返回FailureAsync()前调用context.ModelState.AddModelError("My Key", "Couldn't really understand you.")

正确方案解析

推荐使用ModelState添加错误的方式

这是符合ASP.NET Core框架设计意图的标准做法,原因如下:

  1. ModelState的核心作用:ModelState是框架用于存储模型绑定、验证过程中所有错误信息的容器。当ModelState存在错误时,API框架会自动返回HTTP 400响应,并将错误信息序列化后返回给客户端,这是REST API处理请求错误的规范方式。
  2. 直接抛异常的问题:抛出异常更适合处理未预期的系统级错误,而非预期内的格式解析失败。这种方式会绕过框架的模型验证流程,不利于统一错误格式的维护,还可能被全局异常处理中间件拦截后返回非标准的错误响应。

优化后的实现代码

public override async Task<InputFormatterResult> ReadRequestBodyAsync(
        InputFormatterContext context, Encoding effectiveEncoding)
{
    try
    {
        // 自定义解析逻辑
        var parsedModel = await ParseOurFormatAsync(context.HttpContext.Request.Body, effectiveEncoding);
        return await InputFormatterResult.SuccessAsync(parsedModel);
    }
    catch (InvalidDataException ex)
    {
        logger.LogError(ex, "Failed to parse request content in application/x-ourformat");
        // 添加全局模型错误,空键表示错误针对整个请求体
        context.ModelState.AddModelError(string.Empty, "请求内容格式错误,无法解析");
        return await InputFormatterResult.FailureAsync();
    }
}

关于400 vs 415的选择

  • 415状态码适用于请求的Content-Type不被服务端支持的场景,这种情况框架通常会自动处理,无需自定义逻辑。
  • 若Content-Type正确但内容格式不符合要求,返回400状态码更准确,因为400表示"错误的请求",对应内容解析失败的场景。

内容的提问来源于stack exchange,提问作者Martin Ba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 05:20:29