C# 为WebAPI中的枚举描述实现TypeConverter

C# 为WebAPI中的枚举描述实现TypeConverter,c#,asp.net-core-webapi,C#,Asp.net Core Webapi,我在枚举上使用DescriptionAttribute来提供包含空格的描述。我创建了一些扩展方法,它们将返回枚举的字符串描述和/或从字符串描述返回枚举值 现在,我希望我的WebAPI使用这些扩展方法来处理枚举类型转换,而不是默认的TypeConverter,这样我就可以传递一个值,如“Car Wash”,并将其映射到枚举 是否有方法将默认字符串重写为Enum TypeConverter 环境 .NetCore 2.x 更新-我的当前代码 当控制器将一个对象序列化为JSON并发送到客户端时,我当前

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

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

是否有方法将默认字符串重写为Enum TypeConverter

环境 .NetCore 2.x

更新-我的当前代码

当控制器将一个对象序列化为JSON并发送到客户端时,我当前的代码做得很好。给定下面的
Enum
,Enum值为0将导致客户端获得字符串“Mental Health”--完美。但是,现在当客户端将“心理健康”发送回服务器时,我需要将其转换回
AgencyTpes.MentalHealth
。现在,绑定引擎抛出一个错误

//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));
     }
}
更新2-WebAPI

下面是控制器和域对象的示例代码

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)
    {
       ...
    }
  }
公共类代理
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共代理类型代理类型{get;set;}
...
}
[ApiController]
公共类代理控制器:ControllerBase
{
[HttpPost]
公共异步任务代理([FromForm]代理)
{
...
}
}

您可以尝试覆盖默认的
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
}

看看林克先生。这是指向正确方向的指针吗?当然,您必须实现自己的转换器。我认为这没有帮助。我已经添加了转换器,如该示例所示。不幸的是,WebAPI TypeConverter似乎没有利用添加到JsonOptions的转换器。这有帮助吗?这就是我目前拥有的所有代码--现在我只需要知道如何让WebAPI绑定引擎使用我的转换器将字符串转换为枚举。@RHarris直接在模型成员上应用转换器,以便绑定器将使用它来反序列化我尝试添加的值
[TypeConverter(typeof(StringAnnotationEnumConverter))]
但是我在System.ComponentModel.TypeConverter中得到了System.FormatException。我想知道这是否是因为
StringEnumConverter
不是
TypeConverter
[TypeConverter(typeof(MyEnumConverter))]
public enum AgencyTypes {
    [System.ComponentModel.Description("Mental Health")]
    MentalHealth,
    Corrections,
    [System.ComponentModel.Description("Drug & Alcohol")]
    DrugAndAlcohol,
    Probation
}