使用 [FromQuery] 解析枚举值

Kli*_*ker 5 enums html-parsing .net-core asp.net-core

我正在使用该[FromQuery]属性将Get请求参数解析为复杂对象。例如:

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

}
Run Code Online (Sandbox Code Playgroud)

SomeArguments对象的属性之一是enum.

public enum SomeEnum { EnumValue01, EnumValue02 }

public class SomeArguments 
{
    [FromQuery(Name = "enum_arg")]
    public SomeEnum EnumArgument { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我用类似的东西调用端点:

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”对此声明类型无效。它仅对“属性、索引器、参数”有效

Ale*_*der 6

您可以EnumMemberAttribute结合使用StringEnumConverter来实现您的目标。定义SomeEnum如下

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

    [EnumMember(Value = "eval02")]
    EnumValue02
}
Run Code Online (Sandbox Code Playgroud)

此时,只有在使用Newtonsoftjson 序列化程序时,它才会按照您的需要工作。例如,当控制器期望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;
    }
}
Run Code Online (Sandbox Code Playgroud)

更新SomeEnum定义以使用JsonModelBinder

[JsonConverter(typeof(StringEnumConverter))]
[ModelBinder(typeof(JsonModelBinder))]
public enum SomeEnum
Run Code Online (Sandbox Code Playgroud)

  • @Neyoh如果您在示例中从“test-uno”中删除破折号,则该名称将仅与“TestUno”成员名称匹配,这就是它起作用的原因。尝试不带破折号的“[EnumMemberAttribute(Value = "uno")] `,看看它是如何工作的 (2认同)