Принять параметр enum из заголовка HTTP в действии контроллера в ядре ASP.NET CoreC#

Место общения программистов C#
Ответить
Anonymous
 Принять параметр enum из заголовка HTTP в действии контроллера в ядре ASP.NET Core

Сообщение Anonymous »

В моем приложении ASP.NET Core я хочу выставить конечную точку API, которая принимает один входной параметр, который представляет собой следующее enum Тип:

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

public enum MyEnum
{
[EnumMember(Name = "VALUE-1")]
VALUE_1,

[EnumMember(Name = "VALUE-2")]
VALUE_2
}
Я хочу, чтобы параметр был предоставлен в заголовке http с именем x-customheader , и я хочу использовать свои значения перечисления '[enummember] атрибуты для десериализации (из-за ограничений именования C# lang), поэтому я написал Custom Model Binder:

' pre class =" lang-class = "lang-class ="

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

public class StringEnumMemberModelBinder : IModelBinder
{
Task IModelBinder.BindModelAsync(ModelBindingContext bindingContext)
{
ValueProviderResult valueProviderResult =
bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
string? rawData = valueProviderResult.FirstValue;

if (string.IsNullOrEmpty(rawData))
{
bindingContext.ModelState.TryAddModelError(
bindingContext.ModelName,
"The value is required."
);
bindingContext.Result = ModelBindingResult.Failed();
}
else if (EnumHelper.TryParse(rawData, bindingContext.ModelType, out Enum result)) // EnumHelper logic omitted
{
bindingContext.Result = ModelBindingResult.Success(result);
}
else
{
bindingContext.ModelState.TryAddModelError(
bindingContext.ModelName,
$"Could not parse value '{rawData}' as '{bindingContext.ModelType.FullName}'."
);
bindingContext.Result = ModelBindingResult.Failed();
}
}
}
< /code>
Затем я применил связующую модель на уровне конечной точки, используя атрибуты: < /p>
public class MyController
{
[HttpGet]
[Route("")]
public async Task Get(
[FromHeader(Name = "X-CustomHeader")]
[ModelBinder(typeof(StringEnumMemberModelBinder))]
MyEnum e
)
{
// [...]
}
}
Этот код не удается, потому что поставщик значений Binder Model не может получить значение заголовка (т.е. valueproviderresult.firstvalue is null в stringenummembermodelbinder класс). Тот же код работает при использовании атрибута [fromQuery] , а не [fromHeader] и передачи моего параметра в QueryString. Я могу получить доступ к значению заголовка, используя контекст HTTP в объекте привязки контекста, но я бы предпочел, чтобы моя модель переплета работала одинаково во всех случаях (когда источник параметра из QueryString или из заголовка HTTP).
то, что я мог бы наблюдать во время отладки, является то, что BindingContext.ValuePRovverVerVerVerVerVerVerVerVerVerVerVerVerVerVerVIDE Это в основном коллекция поставщиков стоимости, предоставленных для операции. Когда я использую атрибут [fromheader] , коллекция состоит из routevalueprovider и опционы QuerystringValueProvider , если в запросе присутствует строка запроса. Похоже, что оба поставщика не могут обнаружить параметр в заголовке. С другой стороны, когда я использую [fromQuery] , коллекция состоит только из QuerystringValueProvider (если присутствует запрос QueryString) и успешно обнаруживает параметр в QueryString (как и ожидалось). Я ожидал, что поведение будет аналоговым при использовании [OffQuery] или [FromHeader] , то есть поставщиком значений будет QueryStringValueProvider в первом случае, а также какой -то вид HeadervalueProvider в последнем. Я очень уверен, что это разумное ожидание, потому что привязка контекста привязки правильно обнаруживает мой предполагаемый источник параметров в обоих случаях ( в первом случае, заголовок в последнем).
Как я могу обойти все это?

Подробнее здесь: https://stackoverflow.com/questions/797 ... p-net-core
Ответить

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

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

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

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

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