Код: Выделить всё
public enum MyEnum
{
[EnumMember(Name = "VALUE-1")]
VALUE_1,
[EnumMember(Name = "VALUE-2")]
VALUE_2
}
Код: Выделить всё
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();
}
}
}
Код: Выделить всё
public class MyController
{
[HttpGet]
[Route("")]
public async Task Get(
[FromHeader(Name = "X-CustomHeader")]
[ModelBinder(typeof(StringEnumMemberModelBinder))]
MyEnum e
)
{
// [...]
}
}
Я могу получить доступ к значению заголовка, используя контекст HTTP в объекте контекста привязки, но я бы предпочел, чтобы моя связка модели работала одинаково во всех случаях (когда источником параметра является строка запроса или заголовок HTTP).
Во время отладки я мог наблюдать, что bindingContext.ValueProvider имеет тип CompositeValueProvider. По сути, это набор поставщиков значений, доступных для операции. Когда я использую атрибут [FromHeader], коллекция состоит из RouteValueProvider и, возможно, QueryStringValueProvider, если в запросе присутствует строка запроса.
Похоже, что оба поставщика не могут обнаружить параметр в заголовке. С другой стороны, когда я использую [FromQuery], коллекция состоит только из QueryStringValueProvider (если строка запроса присутствует) и успешно обнаруживает параметр в строке запроса (как и ожидалось).
Я не уверен, что здесь происходит на самом деле. Я ожидал, что поведение будет аналогичным при использовании [FromQuery] или [FromHeader], т. е. поставщиком значения будет QueryStringValueProvider в первом случае и какой-то HeaderValueProvider во втором. Я вполне уверен, что это разумное ожидание, поскольку BindingSource контекста привязки правильно определяет предполагаемый источник параметра в обоих случаях (
Код: Выделить всё
QueryКак обойти все это?
Подробнее здесь: https://stackoverflow.com/questions/797 ... p-net-core
Мобильная версия