Проблема в том, что он не отображается в OpenAPI/Swagger в качестве поля параметра заголовка.
Мне нужен параметр заголовка Accept-Language, чтобы он отображался для конечных точек, имеющих CurrentLanguage Параметр
Что я пробовал
Я считаю, что CurrentLanguage должен реализовать IEndpointParameterMetadataProvider и добавить соответствующие метаданные, но мне не удалось это сделать.
Просто добавляю builder.Metadata.Add(new FromHeaderAttribute { Name = "Accept-Language" }); ничего.
Я также пытался добавить метаданные LanguageParameterMetadata(параметрParameterInfo): IParameterBindingMetadata, но это тоже бесполезно, поскольку этот интерфейс содержит параметр ParameterInfo, который имеет защищенный конструктор, а CustomAttributes не редактируются.
Минимальное воспроизведение с проблемой:
Код: Выделить всё
using Microsoft.AspNetCore.Mvc;
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();
app.MapGet("/test", (CurrentLanguage language, [FromHeader] string testHeader) => language.Value.Code);
app.Run();
record CurrentLanguage(Language Value) : IBindableFromHttpContext
{
public static ValueTask BindAsync(HttpContext context, ParameterInfo parameter)
{
var langValue = context.Request.Headers.AcceptLanguage.FirstOrDefault() ?? "en";
var language = new Language(langValue);
return ValueTask.FromResult(new CurrentLanguage(language))!;
}
}
record Language(string Code);
Код: Выделить всё
app.MapGet("/test", (CurrentLanguage language, [FromHeader] string testHeader) => language.Value.Code)
.WithOpenApi(operation =>
{
operation.Parameters.Add(new OpenApiParameter
{
Name = "Accept-Language",
In = ParameterLocation.Header,
Required = false,
Description = "Language preference (e.g. en-US, ka-GE)",
Schema = new OpenApiSchema
{
Type = JsonSchemaType.String
}
});
return operation;
});
- Устарело.
- Необходимо применять вручную к каждой конечной точке.
Код: Выделить всё
record CurrentLanguage(Language Value) : IBindableFromHttpContext, IEndpointParameterMetadataProvider
{
public static ValueTask BindAsync(HttpContext context, ParameterInfo parameter)
{
var langValue = context.Request.Headers.AcceptLanguage.FirstOrDefault() ?? "en";
var language = new Language(langValue);
return ValueTask.FromResult(new CurrentLanguage(language))!;
}
public static void PopulateMetadata(ParameterInfo parameter, EndpointBuilder builder)
{
var p = (IParameterBindingMetadata)builder.Metadata[3];
var m = new LanguageParameterBindingMetadata("Accept-Language", p.HasTryParse, p.HasBindAsync, p.ParameterInfo, p.IsOptional);
builder.Metadata.Add(m);
}
}
class LanguageParameterBindingMetadata(string name, bool hastryParse, bool hasBindAsync, ParameterInfo parameterInfo, bool isOptonal)
: IParameterBindingMetadata
{
public string Name => name;
public bool HasTryParse => hastryParse;
public bool HasBindAsync => hasBindAsync;
public ParameterInfo ParameterInfo => parameterInfo;
public bool IsOptional => isOptonal;
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... definition
Мобильная версия