我可以使用 System.Text.Json 通过私有构造函数反序列化 Json 吗?

2024-04-22

想知道是否可以拥有私有构造函数并使用新的 System.Text.Json 序列化器。

public class MyModel
{
    public string Name { get; set; }
    public string Data { get; set; }

    private MyModel() 
    {
        // use me for when deserializing
    }

    public MyModel(string name, string data)
    {
        Name = name;
        Data = data;
    }
}

简单的往返。

var model = new MyModel("doo", "doo");
var json = JsonSerializer.Serialize(model, new JsonSerializerOptions
{
    WriteIndented = true
});

// no to go because of there is no parameterless constructor defined for this object.
var rehydrated = JsonSerializer.Deserialize<MyModel>(json);

.NET 8.0 中的更新

只需添加JsonConstructorAttribute私有构造函数如下:

public class Employee
{
   [JsonConstructor] // This will work from .NET 8.0
   private Employee()
   {
   }

   private Employee(int id, string name)
   {
     Id = id;
     Name = name;
   }

   [JsonInclude]
   public int Id { get; private set; }

   [JsonInclude]
   public string Name { get; private set; }

   public static Employee Create(int id, string name)
   {
     Employee employee = new Employee(id, name);
     return employee;
   }
}

.NET 7.0 中的更新

从 .NET 7.0 开始,可以通过编写自己的 ContractResolver 使用私有无参数构造函数来完成反序列化,如下所示:

public class PrivateConstructorContractResolver : DefaultJsonTypeInfoResolver
{
   public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
   {
       JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options);

       if (jsonTypeInfo.Kind == JsonTypeInfoKind.Object && jsonTypeInfo.CreateObject is null)
       {
         if (jsonTypeInfo.Type.GetConstructors(BindingFlags.Public | BindingFlags.Instance).Length == 0)
         {
            // The type doesn't have public constructors
            jsonTypeInfo.CreateObject = () => 
                Activator.CreateInstance(jsonTypeInfo.Type, true);
         }
       }

      return jsonTypeInfo;
   }
}

使用方法如下:

private static void Main(string[] args)
{
    JsonSerializerOptions options = new JsonSerializerOptions
    {
       TypeInfoResolver = new PrivateConstructorContractResolver()
    };

    Employee employee = Employee.Create(1, "Tanvir");
    string jsonString = JsonSerializer.Serialize(employee);
    Employee employee1 = JsonSerializer.Deserialize<Employee>(jsonString , options);
}

public class Employee
{
   private Employee()
   {
   }

   private Employee(int id, string name)
   {
     Id = id;
     Name = name;
   }

   [JsonInclude]
   public int Id { get; private set; }

   [JsonInclude]
   public string Name { get; private set; }

   public static Employee Create(int id, string name)
   {
     Employee employee = new Employee(id, name);
     return employee;
   }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以使用 System.Text.Json 通过私有构造函数反序列化 Json 吗? 的相关文章

  • 更新面板工作速度非常慢

    我正在编写一个用户可以注册的应用程序 注册时 可以选择多个选项 并根据这些注册字段可见或不可见以及是否必需 我想出了一个想法 所有字段都将位于 updatePanel 中 当用户更改注册选项时 我将在服务器端设置这些字段的可见性 它可以工作
  • 将类对象放置在向量中?

    我注意到我可以将一个类放置在一个向量中 这是我的程序 我收到以下错误 out blackjack exe blackjack obj blackjack obj error LNK2019 unresolved external symbo
  • 前向声明类型和“已声明为类类型的非类类型”

    我对以下代码有问题 template
  • 从复选框列表中选择循环生成的复选框中的一个复选框

    抱歉我的英语不好 在我的 ASP NET 网站上 我从 SQL 表导入软件列表 看起来像这样 但实际上要长得多 Microsoft Application Error Reporting br br Microsoft Applicatio
  • 如何将 SOLID 原则应用到现有项目中

    我对这个问题的主观性表示歉意 但我有点卡住了 我希望之前处理过这个问题的人能够提供一些指导和建议 我有 现在已经成为 一个用 C 2 0 编写的非常大的 RESTful API 项目 并且我的一些类已经变得巨大 我的主要 API 类就是一个
  • 有些有助于理解“产量”

    在我不断追求少吸的过程中 我试图理解 产量 的说法 但我不断遇到同样的错误 someMethod 的主体不能是迭代器块 因为 System Collections Generic List 不是迭代器接口类型 这是我被卡住的代码 forea
  • 处理右值时的 insert 与 emplace

    std string myString std unordered set
  • 强制初始化模板类的静态数据成员

    关于模板类的静态数据成员未初始化存在一些问题 不幸的是 这些都没有能够帮助我解决我的具体问题的答案 我有一个模板类 它有一个静态数据成员 必须为特定类型显式实例化 即必须专门化 如果不是这种情况 使用不同的模板函数应该会导致链接器错误 这是
  • Eigen 和 OpenMP:由于错误共享和线程开销而没有并行化

    系统规格 Intel Xeon E7 v3 处理器 4 插槽 16 核 插槽 2 线程 核心 Eigen 系列和 C 的使用 以下是代码片段的串行实现 Eigen VectorXd get Row const int j const int
  • 不同 C++ 文件中的相同类名

    如果两个 C 文件具有相同名称的类的不同定义 那么当它们被编译和链接时 即使没有警告也会抛出一些东西 例如 a cc class Student public std string foo return A void foo a Stude
  • 获取没有显式特征的整数模板参数的有符号/无符号变体

    我希望定义一个模板类 其模板参数始终是整数类型 该类将包含两个成员 其中之一是类型T 另一个作为类型的无符号变体T 即如果T int then T Unsigned unsigned int 我的第一直觉是这样做 template
  • 是否使用 C# 数据集? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我对 C 中的数据集概念有点困惑 编码 ASP NET 站点 但这并不重要 在我的阅读中 我了解到它们 本质上 用作我的应用程序和我的
  • 如何将AVFrame转换为glTexImage2D使用的纹理?

    如您所知 AVFrame 有 2 个属性 pFrame gt data pFrame gt linesize 当我从视频 sdcard test mp4 android平台 读取帧后 并将其转换为RGB AVFrame副 img conve
  • 如何递归取消引用指针(C++03)?

    我正在尝试在 C 中递归地取消引用指针 如果传递一个对象 那就是not一个指针 这包括智能指针 我只想返回对象本身 如果可能的话通过引用返回 我有这个代码 template
  • 如果输入被重定向则执行操作

    我想知道如果我的输入被重定向 我应该如何在 C 程序中执行操作 例如 假设我有已编译的程序 prog 并且我将输入 input txt 重定向到它 我这样做 prog lt input txt 我如何在代码中检测到这一点 一般来说 您无法判
  • C++ - 多维数组

    处理多维数组时 是否可以为数组分配两种不同的变量类型 例如你有数组int example i j 有可能吗i and j是两种完全不同的变量类型 例如 int 和 string 听起来您正在寻找 std vector
  • 如何在 C# 中创建异步方法?

    我读过的每一篇博客文章都会告诉您如何在 C 中使用异步方法 但由于某些奇怪的原因 从未解释如何构建您自己的异步方法来使用 所以我现在有这段代码使用我的方法 private async void button1 Click object se
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • Visual Studio 2015:v120 与 v140?

    仅供参考 Win10 x64 我今天开始尝试 Visual Studio 2015 在弄清楚如何运行 C C 部分后 我尝试加载一个大型个人项目 该项目使用非官方的glsdk http glsdk sourceforge net docs
  • 我可以使用 lambda 函数或 std::function 对象来代替函数指针吗?

    我有一个需要使用的库 它定义了以下内容 typedef void CallbackFunction const int i 并且有一个注册回调的函数 如下所示 void registerCallback CallbackFunction p

随机推荐