gpt4 book ai didi

asp.net-core - 使用 AspNet [FromQuery] 模型绑定(bind)中的 EnumMember 值反序列化枚举

转载 作者:行者123 更新时间:2023-12-05 04:27:11 25 4
gpt4 key购买 nike

我在 .NET 6 Microsoft.NET.Sdk.Web 项目中有一个端点,它使用标准 [FromQuery] 将查询字符串反序列化为 .NET 对象

[Route("[controller]")]
public class SamplesController
: ControllerBase
{
[HttpGet]
public IActionResult Get([FromQuery]QueryModel queryModel)
{
if (!queryModel.Status.HasValue)
{
return BadRequest("Problem in deserialization");
}

return Ok(queryModel.Status.Value.GetEnumDisplayName());
}
}

模型包含一个枚举

public class QueryModel
{
/// <summary>
/// The foo parameter
/// </summary>
/// <example>bar</example>
public string? Foo { get; init; } = null;

/// <summary>
/// The status
/// </summary>
/// <example>on-hold</example>
public Status? Status { get; set; } = null;
}

并且枚举有 EnumMember 属性,我想用它来反序列化。

public enum Status
{
[EnumMember(Value = "open")]
Open,

[EnumMember(Value = "on-hold")]
OnHold
}

默认情况下,.NET 6 在反序列化时不考虑 EnumMember

目标是能够发送请求,例如

http://localhost:5000/Samples?Foo=bar&Status=on-hold 

并让 Controller 的操作通过使用其 EnumMember

使用适当的 Status.OnHold 值反序列化 QueryModel

我试过一个包含转换器的扩展库,但没有成功,但是在使用 [FromQuery] 时转换器没有被触发。参见 https://github.com/Macross-Software/core/issues/30

我添加了一个项目来重现问题并作为沙箱提供解决方案** https://gitlab.com/sunnyatticsoftware/issues/string-to-enum-mvc/-/tree/feature/1-original-problem

注意:我需要一个解决方案,其中 Enum 和 不需要任何外部依赖项(仅 .NET sdk)。

最佳答案

自定义枚举转换器可能是您的选择。通过利用现有的 EnumConverter 类,我们需要有一个自定义的 ConvertFrom 方法:

public class CustomEnumConverter : EnumConverter
{
public CustomEnumConverter([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.PublicFields)] Type type) : base(type)
{
}

public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
if (value is string strValue)
{
try
{
foreach (var name in Enum.GetNames(EnumType))
{
var field = EnumType.GetField(name);
if (field != null)
{
var enumMember = (EnumMemberAttribute)(field.GetCustomAttributes(typeof(EnumMemberAttribute), true).Single());
if (strValue.Equals(enumMember.Value, StringComparison.OrdinalIgnoreCase))
{
return Enum.Parse(EnumType, name, true);
}
}
}
}
catch (Exception e)
{
throw new FormatException((string)value, e);
}
}

return base.ConvertFrom(context, culture, value);
}
}

然后将转换器装饰到您的模型类:

[TypeConverter(typeof(CustomEnumConverter))]
public enum Status
{
[EnumMember(Value = "open")]
Open,

[EnumMember(Value = "on-hold")]
OnHold
}

然后我们可以解析“on-hold”。您可能还想覆盖 ConverTo() 以打印 EnumMember 值以大摇大摆。这有点老套,但如果您想要一个纯 .NET 解决方案,这应该是最小可行的解决方案之一。

enter image description here

关于asp.net-core - 使用 AspNet [FromQuery] 模型绑定(bind)中的 EnumMember 值反序列化枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72886747/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com