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

如何让ASP.NET ApiExplorer与NSwag将强类型Id识别为字符串?

解决ASP.NET 6中ApiExplorer将强类型Id识别为复杂对象的问题

你的问题根源在于ASP.NET的ApiExplorer默认会将带属性的Id记录识别为复杂对象,进而导致NSwag生成多余的参数。以下是三种可行的解决方案:

方案1:为强类型Id添加TypeConverter

ApiExplorer会根据类型的转换能力判断是否为简单类型,给Id实现TypeConverter后,框架会将其识别为可与字符串互转的简单类型。

首先实现自定义类型转换器:

public class IdTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string str && Guid.TryParse(str, out var guid))
        {
            return new Id(guid);
        }
        return base.ConvertFrom(context, culture, value);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string) && value is Id id)
        {
            return id.Value.ToString();
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }
}

然后给Id记录标记类型转换器特性:

[TypeConverter(typeof(IdTypeConverter))]
public record Id(Guid Value);

方案2:自定义IApiDescriptionProvider修改参数描述

通过实现IApiDescriptionProvider,直接修改ApiExplorer生成的参数元数据,将Id类型替换为字符串类型。

实现自定义Provider:

public class IdApiDescriptionProvider : IApiDescriptionProvider
{
    public void OnProvidersExecuting(ApiDescriptionProviderContext context)
    {
        foreach (var apiDescription in context.Results)
        {
            var targetParams = apiDescription.ParameterDescriptions
                .Where(p => p.ParameterType == typeof(Id))
                .ToList();

            foreach (var param in targetParams)
            {
                apiDescription.ParameterDescriptions.Remove(param);
                apiDescription.ParameterDescriptions.Add(new ApiParameterDescription
                {
                    Name = param.Name,
                    ParameterType = typeof(string),
                    Source = param.Source,
                    ModelMetadata = context.ModelMetadataProvider.GetMetadataForType(typeof(string))
                });
            }
        }
    }

    public void OnProvidersExecuted(ApiDescriptionProviderContext context)
    {
        // 无需额外处理
    }
}

在Program.cs中注册该服务:

builder.Services.TryAddEnumerable(ServiceDescriptor.Transient<IApiDescriptionProvider, IdApiDescriptionProvider>());

方案3:直接配置NSwag的Schema生成规则

绕过ApiExplorer的判断,在NSwag层面强制将Id类型处理为字符串类型:

在Program.cs的NSwag配置中添加自定义Schema处理器:

builder.Services.AddOpenApiDocument(settings =>
{
    settings.SchemaGenerator.SchemaProcessors.Add(new IdSchemaProcessor());
});

public class IdSchemaProcessor : ISchemaProcessor
{
    public void Process(SchemaProcessorContext context)
    {
        if (context.Type == typeof(Id) || context.ParameterInfo?.ParameterType == typeof(Id))
        {
            context.Schema.Type = "string";
            context.Schema.Format = "uuid";
            context.Schema.Properties.Clear();
            context.Schema.Required.Clear();
        }
    }
}

内容的提问来源于stack exchange,提问作者Christian Klemm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:15:35