gpt4 book ai didi

c# - 为 WebAPI 中的 Enum 描述实现一个 TypeConverter

转载 作者:行者123 更新时间:2023-12-04 14:19:17 43 4
gpt4 key购买 nike

我在枚举上使用 DescriptionAttribute 来提供包含空格的描述。我创建了一些扩展方法,它们将返回枚举的字符串描述和/或从字符串描述返回枚举值。

现在我希望我的 WebAPI 使用这些扩展方法来处理枚举类型转换而不是默认的 TypeConverter,这样我就可以传递像 "Car Wash" 这样的值并将其映射到一个枚举。

有没有办法将默认字符串覆盖为 Enum TypeConverter?

环境.NetCore 2.x

更新 - 我当前的代码

当 Controller 将对象序列化为 JSON 以发送给客户端时,我当前的代码非常有用。给定以下 Enum,枚举值为 0 将导致客户端获得字符串“Mental Health”——完美。但是,现在当客户端将“心理健康”发送回服务器时——我需要将其转换回 AgencyTpes.MentalHealth。现在,绑定(bind)引擎抛出一个错误。

//Example Enum
public enum AgencyTypes {
[Description("Mental Health")]
MentalHealth,
Corrections,
[Description("Drug & Alcohol")]
DrugAndAlcohol,
Probation
}

使用 DescriptionAttribute 的我的枚举扩展

public static class EnumExtensions
{
public static string ToDisplayString(this Enum values)
{
var attribute = value.GetType().GetMember(value.ToString())
.FirstOrDefault()?.GetCustomAttribute<DescriptionAttribute>();
return attribute ?.Description ?? value.ToString();
}

public static object GetValueFromDescription(string description, Type enumType)
{
return Convert.ChangeType(LookupDescription(description,enumType),enumType);
}

public static T GetValueFromDescription<T>(string description) where T: struct
{
return (T)LookupDescription(description, typeof(T));
}

private static object LookupDescription(string description, Type enumType)
{
if(!enumType.IsEnum)
throw new ArgumentException("Type provided must be an Enum", enumType.Name);

foreach(var field in enumType.GetFields())
{
var attribute = Attribute.GetCustomAttribute(field, tyepof(DescriptionAttribute)) as DescriptionAttribute;
if((attribute != null && attribute.Description == description)
|| field.Name == description)
{
return field.GetValue(null);
}
}
throw new ArgumentException($"Requested value for '{description}' in enum {enumType.Name} was not found", nameof(description));
}
}

我的 JSON 覆盖使 Controller 能够将枚举转换为字符串

//Startup.cs
services.AddMvc().SetCompatibilityVersion(Compatibility.Version_2_2)
.AddJsonOptions(options =>
{
options.SerializerSettings.Converters.Add(new StringAnnotationEnumConverter());
});


public class StringAnnotationEnumConverter : StringEnumConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
var value = token.ToString();
if(reader.TokenType == JsonToken.String)
return EnumExtensions.GetValueFromDescription(value, objectType);
else
return base.ReadJson(reader, objectType, existingValue, serializer);
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if(value == null)
{
writer.WriteNull();
return;
}

Enum e = (Enum)value;
string enumName = e.ToDisplayString();
if(string.IsNullOrWhiteSpace(enumName))
throw new JsonSerializationException(String.Format("Integer value {0} is not allowed.",e.ToString("D")));

writer.WriteValue(enumName);
}
}

更新 2 - WebAPI

这是 Controller 和域对象的示例代码

public class Agency 
{
public int Id {get; set;}
public string Name {get; set;}
public AgencyTypes AgencyType {get; set;}
...
}


[ApiController]
public class AgencyController : ControllerBase
{
[HttpPost]
public async Task<IActionResult> Agency([FromForm] Agency agency)
{
...
}
}

最佳答案

您可以尝试覆盖默认的 EnumConverter 来执行您的自定义属性检查

public class MyEnumConverter: EnumConveter {
public MyEnumConverter(Type type) : base(type) {
}


public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
if (value is string) {
var enumString = (string)value;
return EnumExtensions.GetValueFromDescription(enumString, EnumType);
}
return base.ConvertFrom(context, culture, value);
}
}

并用 TypeConverter 属性装饰你的枚举

[TypeConverter(typeof(MyEnumConverter))]
public enum AgencyTypes {
[System.ComponentModel.Description("Mental Health")]
MentalHealth,
Corrections,
[System.ComponentModel.Description("Drug & Alcohol")]
DrugAndAlcohol,
Probation
}

关于c# - 为 WebAPI 中的 Enum 描述实现一个 TypeConverter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56742023/

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