带有数据注释的枚举类型的Json.NET自定义序列化

阿尔恩·H·比图布克

我想序列化一个枚举类型,以便它返回一个包含枚举的数组作为一个既包含“值”,“名称”又包含数据注释值的对象。我需要序列化方面的帮助。到目前为止,这是我所做的:枚举:

public enum Status
{
    [Display(Name="Active status")]
    Active = 1,
    [Display(Name = "Deactive status")]
    Deactive = 2,
    [Display(Name = "Pending status")]
    Pending = 3
}

应该序列化的DTO对象:

public class ProjectDto
{
    public Type StatusEnum { get; set; }

    public Status CurrentStatus { get; set; }
}

值分配:

var project = new ProjectDto
{
    CurrentStatus = Status.Active, 
    StatusEnum = typeof (Status)
};
var output = JsonConvert.SerializeObject(project);

为了从枚举中获取值,我使用:

Enum.GetNames(typeof(Status)) //To get the names in the enum
Enum.GetValues(typeof(Status)) //To get the values in the enum

要获取数据注释名称值有些棘手,但我在本文中找到了帮助:http : //geeksharp.com/2011/11/02/power-up-your-enumerations/他们已经创建了一个辅助方法,该方法将使用以下方法获取写在数据注释中的值:

public static string GetAttributeValue<T>(this Enum e,
    Func<T, object> selector) where T : Attribute
{
    var output = e.ToString();
    var member = e.GetType().GetMember(output).First();
    var attributes = member.GetCustomAttributes(typeof(T), false);

    if (attributes.Length > 0)
    {
        var firstAttr = (T)attributes[0];
        var str = selector(firstAttr).ToString();
        output = string.IsNullOrWhiteSpace(str) ? output : str;
    }

    return output;
}

您可以使用以下方法获得价值:

.GetAttributeValue<DisplayAttribute>(y => y.Name)

输出应该是这样的

{
    statusEnum: [
        { "value": "1", "name": "Active", "label": "Active status" },
        { "value": "2", "name": "Deactive", "label": "Deactive status" },
        { "value": "3", "name": "Pending", "label": "Pending status" }
    ],
    currentStatus: { "value": "1", "name": "Active", "label": "Active status" }
}

如前所述,我需要帮助来创建自定义Json.NET序列化和反序列化以获得所需的输出。任何帮助将不胜感激。

安德鲁·惠特克

好的,可以稍微清理一下,但是我要编写两个自定义转换器:一个用于Enum类型,另一个用于枚举值:

我创建了一个自定义类以序列化为所需的最终结果:

public class EnumValue
{
    public int Value { get; set; }

    public string Name { get; set; }

    public string Label { get; set; }
}

以及一个静态类,它通过Enums和enum值来创建该类型的实例需要一些工作

public static class EnumHelpers
{
    public static EnumValue GetEnumValue(object value, Type enumType)
    {
        MemberInfo member = enumType.GetMember(value.ToString())[0];

        DisplayAttribute attribute = 
            member.GetCustomAttribute<DisplayAttribute>();

        return new EnumValue
        {
            Value = (int)value,
            Name = Enum.GetName(enumType, value),
            Label = attribute.Name
        };
    }

    public static EnumValue[] GetEnumValues(Type enumType)
    {
        Array values = Enum.GetValues(enumType);

        EnumValue[] result = new EnumValue[values.Length];

        for (int i = 0; i < values.Length; i++)
        {
            result[i] = GetEnumValue(
                values.GetValue(i),
                enumType);
        }

        return result;
    }
}

然后有两个转换器类。第一个序列System.Type化为您想要的对象:

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

        EnumValue[] values = EnumHelpers.GetEnumValues((Type)value);

        serializer.Serialize(writer, values);
    }

    public override object ReadJson(
        JsonReader reader,
        Type objectType,
        object existingValue,
        JsonSerializer serializer)
    {
        throw new NotSupportedException();
    }

    public override bool CanRead { get { return false; } }

    public override bool CanConvert(Type objectType)
    {

        return typeof(Type).IsAssignableFrom(objectType);
    }
}

然后是一个序列化实际枚举值的变量:

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

        EnumValue result = EnumHelpers.GetEnumValue(value, value.GetType());

        serializer.Serialize(writer, result);
    }

    public override object ReadJson(
        JsonReader reader,
        Type objectType,
        object existingValue,
        JsonSerializer serializer)
    {
        throw new NotSupportedException();
    }

    public override bool CanRead { get { return false; } }

    public override bool CanConvert(Type objectType)
    {

        return objectType.IsEnum;
    }
}

这是所有使用方式:

var pr = new ProjectDto();
pr.CurrentStatus = Status.Active;
pr.StatusEnum = typeof(Status);

var settings = new JsonSerializerSettings();
settings.Converters = new JsonConverter[] 
{
    new EnumTypeConverter(),
    new EnumValueConverter()
};
settings.Formatting = Newtonsoft.Json.Formatting.Indented;

string serialized = JsonConvert.SerializeObject(pr, settings);

示例: https //dotnetfiddle.net/BVp7a2

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章