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

如何让Swagger/Swashbuckle使用现有System.Security.Claims.ClaimsPrincipal类型

让Swagger使用原生System.Security.Claims.ClaimsPrincipal类型而非生成自定义版本的问题

我尝试让Swagger使用现有的System.Security.Claims.ClaimsPrincipal类型,而非生成该类型的自定义版本。通过谷歌、ChatGPT等方式查找解决方案均无成效,仅有的少量线索指向通过生成器参数配置的可能方案,但我认为应该可以通过代码实现。

当前代码如下:

services.Configure<SwaggerGenOptions>(options =>
{
    options.SchemaFilter<ClaimsPrincipalFilter>();
    ...
}

public class ClaimsPrincipalFilter : ISchemaFilter
{
    private const string existingNamespace = "System.Security.Claims";

    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type != typeof(ClaimsPrincipal))
            return;

        schema.Reference = new OpenApiReference
        {
            Type = ReferenceType.Schema,
            Id = $"{nameof(ClaimsPrincipal)}, {existingNamespace}"
        };
    }
}

运行后出现错误:

Resolver error at paths./v1/User.get.responses.200.content.text/json.schema.$ref
Could not resolve reference: Could not resolve pointer: /components/schemas/ClaimsPrincipal, System.Security.Claims does not exist in document.

我的需求是直接传递原生System.Security.Claims.ClaimsPrincipal类型的User对象,无需在另一端进行映射或使用“JSON序列化/反序列化”的临时方法。请问我遗漏了什么?

编辑:

我尝试调整Id的设置方式:

schema.Reference = new OpenApiReference
{
    Type = ReferenceType.Schema,
    Id = "System.Security.Claims.ClaimsPrincipal"
};

这消除了Swagger UI中的错误,但我的端点:

[HttpGet]
[ProducesResponseType(typeof(ClaimsPrincipal), StatusCodes.Status200OK)]
public IActionResult GetCurrentUser() =>
    Ok(User);

不再返回结果,且端点上的断点从未触发。Swagger UI调用该端点后的响应如下:

content-length: 0 
date: Fri,02 Jun 2023 15:09:00 GMT 
server: Kestrel 
x-correlation-id: 0HMR3FD1SBL9O:00000009 

更糟的是,Swagger仍在错误的命名空间下生成了新模型:

MyNamspace.Service.Client.v1.Models.ClaimsPrincipal 

这感觉是倒退了一步。

目前我在另一端使用以下映射方法来推进开发:

public static ClaimsPrincipal AsPrincipal(this MyNamspace.Service.Client.v1.Models.ClaimsPrincipal user)
{
    if (user?.Claims == null || !user.Claims.Any())
        return null;

    var claims = user.Claims.Select(x => new Claim(x.Type, x.Value));

    return new ClaimsPrincipal(new ClaimsIdentity(claims));
}

另外,由于存在序列化相关的复杂问题,无论如何都需要使用DTO,之前的尝试其实没有意义。

内容的提问来源于stack exchange,提问作者Serj Sagan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:58:18