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

.NET 6 API如何自动填充扩展ProblemDetails类的默认响应值

在ASP.NET Core中无需手动填充默认属性返回带自定义字段的ProblemDetails

问题背景

默认调用空的NotFound()/BadRequest()时,ASP.NET Core会自动返回符合application/problem+json格式的标准ProblemDetails响应,但如果传入字符串参数(如BadRequest("blah")),响应会退化为普通JSON结构,丢失标准字段。需要在不手动填充type/title/status/traceId等默认属性、不依赖异常处理程序的前提下,返回包含自定义额外属性的标准ProblemDetails响应。

解决方案:自定义Controller扩展方法

通过复用框架内置的ProblemDetailsFactory来自动生成默认属性,再添加自定义字段,最后返回指定内容类型的ObjectResult。

1. 创建扩展方法

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using System.Collections.Generic;

public static class ControllerBaseProblemExtensions
{
    // 通用方法:指定状态码和自定义属性
    public static ObjectResult ProblemWithCustomProps(this ControllerBase controller, int statusCode, IDictionary<string, object> customProps)
    {
        var problemFactory = controller.HttpContext.RequestServices.GetRequiredService<ProblemDetailsFactory>();
        
        // 自动生成对应状态码的标准ProblemDetails(包含type、title、status、traceId)
        var problemDetails = problemFactory.CreateProblemDetails(
            controller.HttpContext,
            statusCode: statusCode
        );
        
        // 添加自定义属性集合
        problemDetails.Extensions.Add("additionalProperties", customProps);
        
        // 返回指定内容类型的响应
        return new ObjectResult(problemDetails)
        {
            StatusCode = statusCode,
            ContentTypes = { "application/problem+json" }
        };
    }

    // 快捷方法:针对404 Not Found
    public static ObjectResult NotFoundWithProps(this ControllerBase controller, IDictionary<string, object> customProps)
    {
        return controller.ProblemWithCustomProps(StatusCodes.Status404NotFound, customProps);
    }

    // 快捷方法:针对400 Bad Request
    public static ObjectResult BadRequestWithProps(this ControllerBase controller, IDictionary<string, object> customProps)
    {
        return controller.ProblemWithCustomProps(StatusCodes.Status400BadRequest, customProps);
    }
}

2. 在Controller中使用

[ApiController]
[Route("api/items")]
public class ItemsController : ControllerBase
{
    [HttpGet("{id}")]
    public IActionResult GetItem(int id)
    {
        if (id <= 0)
        {
            // 返回带自定义属性的400响应
            return this.BadRequestWithProps(new Dictionary<string, object>
            {
                { "example", "blah" },
                { "invalidField", "id" }
            });
        }

        // 模拟未找到资源
        if (true)
        {
            // 返回带自定义属性的404响应
            return this.NotFoundWithProps(new Dictionary<string, object>
            {
                { "example", "blah" },
                { "itemId", id }
            });
        }

        return Ok(new { Id = id, Name = "Test Item" });
    }
}

效果验证

返回的响应会自动包含所有标准ProblemDetails字段,同时带上自定义的additionalProperties,完全符合期望格式:

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
  "title": "Not Found",
  "status": 404,
  "traceId": "00-7d554354b54a8e6be652c2ea65434e55-a453edeb85b9eb80-00",
  "additionalProperties": {
    "example": "blah",
    "itemId": 123
  }
}

方案优势

  • 完全复用框架内置逻辑,无需手动填充任何标准字段
  • 不依赖异常处理,避免为了格式化响应而抛出不必要的异常
  • 保持响应格式统一,始终符合application/problem+json规范

内容的提问来源于stack exchange,提问作者M-Expunged

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 17:06:21