Добавить параметр заголовка в определение конечной точки OpenAPIC#

Место общения программистов C#
Ответить
Anonymous
 Добавить параметр заголовка в определение конечной точки OpenAPI

Сообщение Anonymous »

У меня есть параметр конечной точки IBindableFromHttpContext, который я анализирую из заголовка языка.
Проблема в том, что он не отображается в 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);
Что исправляет проблему, но не решает ее — добавление WithOpenApi:

Код: Выделить всё

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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»