Использование [FromQuery] для анализа значений перечисления - PullRequest
1 голос
/ 30 июня 2019

Я использую атрибут [FromQuery] для разбора Get запросов аргументов в сложный объект. Например:

[HttpGet("some-get-request")]
public IActionResult DoSomething([FromQuery] SomeArguments someArgs)
{

}

Одним из свойств объекта SomeArguments является enum.

public enum SomeEnum { EnumValue01, EnumValue02 }

public class SomeArguments 
{
    [FromQuery(Name = "enum_arg")]
    public SomeEnum EnumArgument { get; set; }
}

И я называю конечную точку чем-то вроде:

http://localhost:1234/api/some-controller/some-get-request?enum_arg=EnumValue01

И все это прекрасно работает. Однако я хочу иметь возможность использовать другое значение перечисления в URL, чем в моем значении перечисления C #. Например, я хочу позвонить, используя URL-адрес, такой как

http://localhost:1234/api/some-controller/some-get-request?enum_arg=eval01

Как я могу это сделать?

Я думал, что мог бы использовать атрибут [FromQuery], как я могу со свойствами, но это не представляется возможным:

'FromQuery' недопустим для этого типа объявления. Он действителен только для свойства, индексатора, параметра

1 Ответ

0 голосов
/ 02 июля 2019

Вы можете использовать EnumMemberAttribute в сочетании с StringEnumConverter для достижения своей цели.Определите SomeEnum следующим образом

[JsonConverter(typeof(StringEnumConverter))]
public enum SomeEnum
{
    [EnumMember(Value = "eval01")]
    EnumValue01,

    [EnumMember(Value = "eval02")]
    EnumValue02
}

. В этот момент он будет работать так, как вам нужно, только когда используется сериализатор Newtonsoft json, например, когда контроллер ожидает запрос POST, а параметр помечен как [FromBody].В вашем случае это не сработает, потому что при привязке [FromQuery] параметр json сериализатор не используется.Чтобы решить эту проблему, создайте пользовательское связующее для модели

public class JsonModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        string rawData = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).FirstValue;
        rawData = JsonConvert.SerializeObject(rawData); //turns value to valid json
        try
        {
            SomeEnum result = JsonConvert.DeserializeObject<SomeEnum>(rawData); //manually deserializing value
            bindingContext.Result = ModelBindingResult.Success(result);
        }
        catch (JsonSerializationException ex)
        {
            //do nothing since "failed" result is set by default
        }


        return Task.CompletedTask;
    }
}

Обновите SomeEnum определение для использования JsonModelBinder

[JsonConverter(typeof(StringEnumConverter))]
[ModelBinder(typeof(JsonModelBinder))]
public enum SomeEnum
...