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

2024-05-03

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

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/ 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 和枚举值:

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);

Example: https://dotnetfiddle.net/BVp7a2 https://dotnetfiddle.net/BVp7a2

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带数据注释的枚举类型的 Json.NET 自定义序列化 的相关文章

  • C++11 中具有 C 链接的复杂类型

    我需要将 C 库的标头包含到我的 C 11 代码中 现在 标头提供了涉及大量的例程和数据结构double complex到处都是 例如 include
  • 通过 TCP/.NET SSLStream 发送文件很慢/无法正常工作

    我正在编写一个与 SSL 配合使用的服务器 客户端应用程序 通过SSLStream 它必须做很多事情 不仅仅是文件接收 发送 目前 它的工作原理是 只有一个连接 我总是使用从客户端 服务器发送数据SSLStream WriteLine 并使
  • 为什么数组不可赋值? [复制]

    这个问题在这里已经有答案了 据我所知 C 标准禁止使用数组作为可修改的左值 即在赋值的左侧 int lhs 4 rhs 4 0 1 2 3 lhs rhs illegal 现在 我一直想知道为什么会这样 我可以看到上面的语句 以及写入数组的
  • 如何修复 TcpClient Ip 标头错误校验和

    我正在使用 System Net Sockets TcpClient 类 但每当我通过网络发送自定义数据包时 我都会在wireshark捕获上看到错误的校验和 我该如何修复它 问题是您在网络接口上设置了校验和卸载 这会导致您的网卡计算校验和
  • 如何获取 PropertyGrid 的单元格值 (c#)?

    如何在 C 中获取属性网格项和项的值 例如 Name Ali LastName Ahmadi Name 和 LastName 是 propertygrid 的 2 个属性 PropertyGrid只是对象的组件模型表示的视图 我会说 查看组
  • 用于轻松动态反射的 C# 库

    是否有任何库 例如开源项目等 可以更轻松地使用复杂的反射 例如动态创建对象或类 检查实例等 Thanks 有一个LinFu http www codeproject com KB cs LinFuPart1 aspx可用的库除了反射之外还可
  • 会员提供商使用还是不使用?

    我正在开发一个使用 Facebook 的网站 现在为了管理用户我想使用MembershipProvider并选择开发一个定制的会员提供商 我的问题是我的数据库架构与标准成员资格架构不匹配 并且提供的用于覆盖的函数采用与我预期不同的参数 例如
  • 等于方法实现助手 (C#)

    每次我编写一些数据类时 我通常都会花很多时间编写 IEquatable 实现 我写的最后一堂课是这样的 public class Polygon public Point Vertices get set 实施 IEquatable 是一项
  • “已经有一个与此命令关联的打开的 DataReader,必须先将其关闭。”

    我正在开发需要连接到另一个数据库以获取一些数据的应用程序 为此 我决定使用 SqlConnection reader 等 我需要执行一些查询 例如首先我需要获取某个用户的卡 ID 之后我需要通过该卡 ID 获取一些数据 这是我的代码 reg
  • 将 pandas DataFrame 写入 unicode 中的 JSON

    我正在尝试将包含 unicode 的 pandas DataFrame 写入 json 但是内置的 to json函数对字符进行转义 我该如何解决 Example import pandas as pd df pd DataFrame a
  • Apple IOS 上的 C# 应用程序 [已关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有基于 C Net 的应用程序 有什么方法可以在 Apple IOS 上运行这些应用程序吗 我没有资
  • gcc 删除内联汇编代码

    看起来 gcc 4 6 2 删除了它认为函数中未使用的代码 test c int main void goto exit handler asm volatile jmp 0x0 exit return 0 拆解main 0x0804840
  • 获取进程的所有 DLL

    我想获取为给定进程加载的所有 dll 的列表 我目前正在使用 NET框架4 0 我知道有一个bug https connect microsoft com VisualStudio feedback details 546430 syste
  • 关于 FirstOrDefault 或 SingleOrDefault

    FirstOrDefault 或 SingleOrDefault 将返回什么类型的数据 假设我的查询返回 3 条记录 例如 empid ename salary 1 joy 1500 2 rob 4500 3 jen 6500 所以如果我们
  • 使用 OpenSSL 库在 C++ 中生成 SHA 哈希值

    如何使用以下命令生成 SHA1 或 SHA2 哈希值OpenSSL https openssl org图书馆 我搜索了谷歌 找不到任何函数或示例代码 从命令行来看 很简单 printf compute sha1 openssl sha1 您
  • 如何查明我的字符串是否包含“micro”Unicode 字符?

    我有一个包含实验室数据的 Excel 电子表格 如下所示 g L ppb 我想测试希腊字母 是否存在 如果发现我需要做一些特别的事情 通常 我会写这样的东西 if cell StartsWith matchSequence lt unive
  • 如何获取数字列的确切类型,包括。规模和精度?

    有没有办法知道列中列的确切类型DataTable 现在我正在这样做 DataTable st dataReader GetSchemaTable foreach DataColumn col in st Columns var type c
  • 通过开源 PCL 使用 API 查看 3D 点云

    我使用 ToF 飞行时间 相机来获取 XYZ 格式的深度数据 为了实现 3D 点云的可视化目的 我想使用开源 PCL 提供的 API 网址为http pointclouds org documentation tutorials pcl v
  • 如何正确对齐 WPF GeometryGroup 中的路径?

    我正在使用一个GeometryGroup在圆的中心绘制一个符号 下面的示例显示了我在对此进行实验时的尝试之一 它具有从同一原点 32 32 出发的三条直线
  • Eclipse (C/C++) 错误:平台关闭后发现作业仍在运行

    当我打开 Eclipse 时 它 在一小时前工作过 但在启动时冻结并给出错误 发生错误 请参阅日志文件 请参阅下面的日志文件 尽管其中一些信息出现在日志中 操作系统 Mac OSX 10 7 5 Eclipse 面向 C C 开发人员的 E

随机推荐

  • 查找使用连接的位置 Excel VBA

    我有大量需要优化的 Excel 2013 工作簿 每个工作簿都有多个工作表和多个数据连接 我正在寻找一种快速列出的方法 连接名称 连接字符串 使用连接的位置 工作表名称或范围很有用 我可以在连接对话框中看到所有这些信息 但无法以编程方式跟踪
  • 从 SQL Server 中的字符串中提取子字符串

    我需要从字符串中提取子字符串的一部分 如下所示 YY 12 Yellow ABC WSA Thisone A SS 4MON DHHE A A 我需要按如下方式提取字符串 Yellow Thisone DHHE 你可以使用这样的东西 dec
  • 未找到“Guzzle\Http\Client”类

    我正在尝试在 sitepoint 上跟进本教程http www sitepoint com guzzle php http client http www sitepoint com guzzle php http client 我这里是一
  • 如何取消 boost asio io_service 帖子

    如何取消已发布的回调 getIoService gt post boost bind MyClass myCallback this 并保持其他发布的回调不变 问题是我有一些对象从不同线程接收事件 并将它们发布到 ioservice 以便处
  • 当 SwingWorker 在后台工作时,对话框没有响应

    基本上我得到了一个以 main 方法作为入口点的 JFrame 在这个主要方法中 程序必须下载一些图像 为了通知用户程序将随时启动 我想显示一个简单的对话框 如果我将对话框设置为模式 我必须在启动程序后关闭它才能触发下载 如果我将其设置为非
  • 如何判断当前运行的 Apple Watch 尺寸/尺寸是 38 毫米还是 42 毫米?

    我们知道Apple Watch有两种屏幕尺寸 38mm和42mm 这WKInterfaceDevice类提供了一个名为的可读属性screenBounds 我写了一个扩展WKInterfaceDevice 尝试添加一种方法来检测当前设备类型
  • 观察 CALayer 中的动画属性变化

    我有一个CABasicAnimation动画 a 的属性CALayer e g bounds origin 我希望能够观察属性随时间的变化 但还没有真正找到一种 100 有效的方法 我尝试使用 KVO 键值观察 presentationLa
  • 如何为 SSMS 2019 (v18) 创建扩展

    SQL Server Management Studio 18 RC1 https learn microsoft com en us sql ssms download sql server management studio ssms
  • 如何自动创建 WPF Viewmodel 属性

    我在 WPF 项目中使用 Visual Studio 17 和 Resharper 该项目向用户显示大量信息 因此我有很多如下所示的属性 private double foo public double Foo get return foo
  • 从 Restful 身份验证迁移到 Devise

    许多 Rails 2 3 应用程序正在使用 Restful Authentication 但该插件似乎与 Rails 3 存在一些问题 在升级到 Rails 3 时 我一直在使用 Devise 有什么办法可以顺利地从 Restful Aut
  • 明确的控制不会处置它们——风险是什么?

    有多个线程 a https stackoverflow com questions 1757116 remove tabpage dispose or clear or both b https stackoverflow com ques
  • 如何使用 JavaScript 或 jQuery 从 URL 下载文件?

    我使用 jQuery fileDownload 插件从 URL 下载文件 fileDownload url contentType text csv contentDisposition attachment filename url sp
  • 正确解析包含“+”字符的字段

    我遇到了一个奇怪的情况 我在其中重现了https github com lgueye uri parameters behavior https github com lgueye uri parameters behavior 自从我们迁
  • 加入或合并 pandas 中的覆盖

    我想对具有日期时间索引的数据框执行联接 合并 追加操作 假设我有df1我想添加df2到它 df2可以有更少或更多的列以及重叠的索引 对于索引匹配的所有行 如果df2具有相同的列df1 我想要的值df1被那些来自df2 我怎样才能获得想要的结
  • 在 ES6 Node.js 中导入“.json”扩展名会引发错误

    我们正在尝试使用 Node js 导出和导入 ES6 模块的新方法 对于我们来说 从package json文件 下面的代码应该做到这一点 import name version from package json 但是 执行时会抛出以下错
  • 如何在 Android 中嵌入和播放 YouTube 视频

    我们可以在 Android 应用程序中观看 YouTube 视频吗 我的意思是 如果我们有 YouTube 上的视频链接 我们可以在 VideoView 或其他小部件中播放它吗 有什么想法吗 答案很简单 是 请查看以下链接 如何在我的 An
  • 如何在fastapi中调用另一个api?

    我能够从另一个 API 获取一个 API 的响应 但无法将其存储在某处 在返回响应之前存储在文件或其他内容中 response RedirectResponse url apiname 我想访问带有标题和正文的发布请求 我想存储此响应内容而
  • Webview 不显示带有颜色的文本

    在我的应用程序中 我在 webview 中显示一些 Html 内容 String webViewConent this is some span style color 2ecc71 sample span string webView l
  • 使用 libsvm 交叉验证后重新训练

    我知道交叉验证用于选择好的参数 找到它们后 我需要在不使用 v 选项的情况下重新训练整个数据 但我面临的问题是 在使用 v 选项训练后 我得到了交叉验证精度 例如 85 没有模型 我看不到 C 和 gamma 的值 在这种情况下我该如何重新
  • 带数据注释的枚举类型的 Json.NET 自定义序列化

    我想序列化一个枚举类型 以便它返回一个数组 其中枚举作为对象 其中包含 值 名称 和数据注释值 我需要序列化方面的帮助 这是我到目前为止所做的 枚举 public enum Status Display Name Active status