JsonConverter如何反序列化为通用对象

2024-02-02

我通过 webapi 发送这个结构:

[DataContract]
public class PacketData
{
    public enum Opcodes
    {
        Hello = 0x00,
        Close = 0x01,
        Serial = 0x02,
        GPIO = 0x04
    }

    [DataMember]
    public object Data { get; private set; }
    [DataMember]
    public Opcodes Opcode { get; private set; }

    public PacketData(Opcodes opcode, object data)
    {
        Data = data;
        Opcode = opcode;
    }
}

我的问题是,当我发送它时,我在服务器端设置我分配给数据几类前。自定义类1、自定义类2

现在,在反序列化时,我得到的不是对象字符串,而是:

{\r\n  \"Cmd\": 5,\r\n  \"BaudRates\": [\r\n    2400,\r\n    4800,\r\n    9600,\r\n    19200,\r\n    38400,\r\n    57600,\r\n    115200\r\n  ],\r\n  \"SerialPorts\": null,\r\n  \"IsOpen\": false,\r\n  \"BaudRate\": 0,\r\n  \"PortName\": null,\r\n  \"WriteCMD\": null,\r\n  \"WriteDATA\": null,\r\n  \"Read\": null\r\n}

所以 Data 是字符串而不是类或 C# 经典对象类型 还有一个问题,我不知道如何从字符串中识别它是 CustomClass1 还是 CustomClass2。

有什么想法如何解决这个问题吗?

Thanks.

编辑:包括反序列化和序列化

[HttpGet("Send", Name = "Send")]
public IActionResult Send()
{
    return Ok(WebAPI.Send(), HttpStatusCode.OK);
}

    public IEnumerable<string> Send()
    {
        List<string> packets = new List<string>();

        foreach (PacketData packet in StaticConfig.SendStack.ToArray())
            packets.Add(JsonConvert.SerializeObject(packet));

        return packets.ToArray();
    }

这是反序列化:

                string json = await client.GetStringAsync(new Uri("http://localhost:5000/api/Send"));

                string[] jsonArray = JsonConvert.DeserializeObject<string[]>(json);

                if (jsonArray.Length == 0)
                    Task.Delay(100).Wait();

                List<PacketData> packets = new List<PacketData>();

                foreach (string j in jsonArray)
                    packets.Add(JsonConvert.DeserializeObject<PacketData>(j));

                foreach (PacketData packet in packets)
                {
                    string p = packet.Data.ToString();

                    bool a = packet.Data is PacketSerialModel; // returns false

                    HandleReceivedData(this, new ReceivedDataArgs(packet));
                }

编辑2: 那么我想要什么呢?

我想将提到的字符串返回到 PacketData.Data 然后我可以使用类似这样的东西:

if(packet.Data is CustomClass1)
{
}
else if(packet.Data is CustomClass2)
{
  var b = packetData as CustomClass2;
  //...
}

目前我的 packet.Data 是字符串,我需要创建这个对象属性并根据 json 设置它们的值。

编辑3: 现在使用

JsonSerializerSettings()
{ TypeNameHandling = TypeNameHandling.Auto }

工作完美,但我必须替换传入的 json 字符串项目名称 就像下面的字符串一样:

["{\"Data\":{\"$type\":\"Shared.PacketSerialModel, ASP_MVC\",\"Cmd\":5,\"BaudRates\":[2400,4800,9600,19200,38400,57600,115200],\"SerialPorts\":null,\"IsOpen\":false,\"BaudRate\":0,\"PortName\":null,\"WriteCMD\":null,\"WriteDATA\":null,\"Read\":null},\"Opcode\":2}"]

我必须将 ASP_MVC 替换为第二个项目名称,除了替换之外还有其他解决方法吗?


要回答您更新的问题,“在交换包含以下内容的 JSON 数据时,如何重新映射程序集名称”$type使用 Json.NET 的不同 .Net 程序集之间的信息”,您有几个选项:

  1. 最简单的方法是将相关类型提取到共享 DLL 中,并从两个程序集中引用该 DLL。这解决了问题并减少了代码重复。

  2. 如果您无法做到这一点,则需要自己编写SerializationBinder https://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationbinder%28v=vs.110%29.aspx,可能继承自 Json.NET 的DefaultSerializationBinder http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_DefaultSerializationBinder.htm,如文档中所述:自定义序列化绑定器 http://www.newtonsoft.com/json/help/html/SerializeSerializationBinder.htm。如果你的课程是not通用,可以简单地重新映射assemblyName:

    public class SimpleAssemblyMappingSerializationBinder : DefaultSerializationBinder
    {
        readonly string oldAssemblyName;
        readonly string newAssemblyName;
    
        public SimpleAssemblyMappingSerializationBinder(string oldAssemblyName, string newAssemblyName)
        {
            this.oldAssemblyName = oldAssemblyName;
            this.newAssemblyName = newAssemblyName;
        }
    
        public override Type BindToType(string assemblyName, string typeName)
        {
            if (assemblyName == oldAssemblyName)
                assemblyName = newAssemblyName;
            return base.BindToType(assemblyName, typeName);
        }
    }
    

    对于类似的活页夹,请参见使用 TypeNameHandling.All 处理命名空间更改 https://stackoverflow.com/questions/9908913/handling-namespace-changes-with-typenamehandling-all.

    但如果你的课程are通用(例如,如果Data有时是一个List<CustomClass3>),你需要解析通用参数 https://msdn.microsoft.com/en-us/library/w3f99sx1%28v=vs.110%29.aspx在类型名称内。有关如何执行此操作的想法,请参阅如何为二进制格式化程序创建 SerializationBinder,以处理类型从一个程序集和命名空间到另一个程序集和命名空间的移动 https://stackoverflow.com/questions/19666511/how-to-create-a-serializationbinder-for-the-binary-formatter-that-handles-the-mo。这个问题是关于BinaryFormatter但答案也适用于 Json.NET。

  3. 要完全省略程序集名称和命名空间,您可以使用来自对象数据类型的 Json 序列化 https://stackoverflow.com/questions/34576078/json-serialization-for-object-data-type用于序列化和反序列化。

  4. 最后,您可以考虑切换到DataContractJsonSerializer https://msdn.microsoft.com/en-us/library/bb412170%28v=vs.110%29.aspx它通过使用间接交换类型信息合同名称而不是原始的 .Net 类型名称。虽然数据契约序列化器通常不如 Json.NET 灵活,但其基于契约的类型信息交换可能更适合这种情况。参见例如如何使用 DataContractSerializer 反序列化具有未命名类型集合的 JSON https://stackoverflow.com/questions/34384838/how-to-deserialize-json-with-unnamed-collection-of-types-using-datacontractseria.

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

JsonConverter如何反序列化为通用对象 的相关文章

  • 简单的 C++ 线程

    我正在尝试在 C Win32 中创建一个线程来运行一个简单的方法 我是 C 线程的新手 但对 C 中的线程非常熟悉 这是我想做的一些伪代码 static void MyMethod int data RunStuff data void R
  • 如何在C编程中获取当前时间(以毫秒为单位)[重复]

    这个问题在这里已经有答案了 可能的重复 如何使用 ANSI C 测量以毫秒为单位的时间 https stackoverflow com questions 361363 how to measure time in milliseconds
  • 静态成员函数与C语言绑定?

    以下 C 代码可使用 Visual C 和 g 进行编译 struct S static void foo extern C void S foo struct T static void foo extern C void T foo a
  • 使用 QTextCursor 选择一段文本

    使用 Qt 框架选择文本片段时遇到问题 例如 如果我有这个文件 没有时间休息 我想选择 ime for r 并从文档中删除这段文本 我应该如何使用 QTextCursor 来做到这一点 这是我的代码 QTextCursor cursor n
  • 当“”可以分配给std::string时,为什么有“clear”方法?

    一个可以用string clear函数清空字符串 也可以使用空双引号 来执行此操作 有什么不同 当您分配一个空字符串时 编译器必须在数据部分存储一个空的 C 字符串 并创建代码以将指向它的指针传递给赋值运算符 然后 赋值运算符必须从数据部分
  • 错误 C2064:术语不计算为采用 1 个参数的函数

    class Student bool Graduate return m bGraduate class School vector
  • 优化对绑定到 DataGridView 的 DataTable 的更新

    我的应用程序中有一个显示一些数据的表单 当我第一次显示表单时 我将一些数据加载到 DataTable 中 然后将 DataTable 绑定到 DataGridView 我还启动了一个异步方法来执行一些较慢的数据库查询 当这些慢查询完成时 我
  • “volatile void function( ... )” 做了什么?

    我见过从语法角度来看 C 函数中 volatile 关键字有多少种用法 https stackoverflow com questions 7643528 how many usage does volatile keyword have
  • 使用 for 循环创建链表

    这是我的结构 struct ListItem int data struct ListItem next 假设链表的第一个节点的 data 0 我想编写一个 for 循环来创建大小为 5 的链表 但我不知道如何工作 我尝试了以下方法 int
  • 如何忽略搜索条件中的空属性

    我有一个不好的要求要做 无论如何 我必须在我的应用程序中实现它 我有一个Track class public class Track public string Name get set public string City get set
  • 用于验证一个参数的多种类型和值的 json 架构

    请在这件事上给予我帮助 我尝试编写一个 json 模式来验证以下对象 json 对象 param value 可能的值 all 任意整数的数组 所以它是一个简单的 json 对象 其中包含一个变量 可以是字符串 all 也可以是任何整数数组
  • 从 JSON 在 Devise 中创建用户

    我正在致力于将运行 Devise 的 Rails 3 1 应用程序与我的 iOS 应用程序集成以进行用户身份验证 我希望用户能够从应用程序注册 然后我可以存储这些凭据以便稍后登录 使用 RestKit 我这样做 IBAction regis
  • C++ std:.auto_ptr 或 std::unique_ptr (支持多个编译器,甚至是旧的 C++03 编译器)?

    我正在尝试更新一些 C 代码 我想转向更现代的代码 c 11 但我仍然需要使用一些较旧的编译器 兼容 c 03 来编译代码 因为支持的平台限制 我知道在 C 11 编译器中 std auto ptr 已被弃用 但由于较旧的编译器支持 我不能
  • 如何从句柄确定进程是 32 位还是 64 位?

    如何从使用 OpenProcess 获取的进程句柄中获取信息 无论进程是 32 位还是 64 位 是的 IsWow64Process 毫无用处 令人烦恼 它的真正意思是 启用了 32 位模拟 如果您在 32 位操作系统上运行 则返回 fal
  • 如何最好地为 Visual Studio 2017 构建的 CMake C++ 项目设置输出目录?

    我使用 Visual Studio 2017 使用 vcxproj 文件构建 C 桌面项目 我喜欢默认行为 其中输出目录是项目下面的子目录 例如 myproj sln myproj vcxproj x64 myproj release my
  • 派生类的聚合初始化

    以下代码无法使用 Visual Studio2017 或在线 GDB 进行编译 我期望它能够编译 因为迭代器只是一个具有类型的类 并且它是从公共继承的 这是不允许的还是在 VS2017 中不起作用 template
  • 使用std::begin()、std::end()将ArrayXd转换为stl向量,

    在我看来我应该能够使用std begin and std end 转换ArrayXd to std vector
  • 字符串常量之前应有非限定 ID

    我目前正在编写一个 C 应用程序 它与 math h 结合实现了振荡器 我拥有的代码应该可以很好地用于该应用程序 尝试编译目标文件 但是我遇到编译器错误 很可能与语法 等有关 我认为这与命名空间有关 错误 终端输出 User Name Ma
  • 如何使用字符串的值将字符串转换为 wstring?

    我是 C 新手 我有这个问题 我有一个名为 DATA DIR 的字符串 需要将其格式化为 wstring string str DATA DIR std wstring temp L s str Visual Studio 告诉我没有与参数
  • “保留供任何使用”是什么意思?

    注意 这是一个c questions tagged c问题 虽然我补充说c questions tagged c 2b 2b如果某些 C 专家可以提供 C 使用与 C 不同的措辞的基本原理或历史原因 在 C 标准库规范中 我们有这个规范文本

随机推荐

  • 正确的 jQuery 图像加载()?

  • 在哪里可以找到 AWS CodeDeploy 部署日志?

    当我选择部署然后单击时 我可以在 Codedeploy 下的 AWS 控制台中看到日志choose events 但它们似乎被截断了 如果我通过 SSH 进入实例 这些 codedeploy 部署日志位于哪里 我看到登录 var log a
  • 将 Python 列表插入 MySQL 的列中

    我有一个列表 我想使用 Python 将该列表的每个元素输入到 MYSQL 列的关联索引单元格中 E g lst 11 22 33 44 55 66 MYSql 列 Data 11 22 33 44 55 66 我怎样才能做到这一点 以下代
  • 什么给出了 java.lang.NoClassDefFoundError?

    我想读取 Excel 文件 但给出 Exception in thread main java lang NoClassDefFoundError org apache xmlbeans XmlObject at ExcelReader m
  • 将 IR 转换为 Z3 公式?

    我在 IR 中有一些代码 并且该代码已经是 SSA 形式 现在我正在尝试将此代码转换为SMT公式 然后将其提供给Z3进行一些验证 我有一些疑问 有没有技术论文详细解释如何将SSA IR转换为SMT公式 我四处寻找 一无所获 对于那些计算指令
  • 从给定索引开始枚举 NSArray 双向搜索(无环绕)

    例子 我有一个包含 15 个对象的数组 我想从给定的索引开始枚举 说从索引 5 开始 然后是上面的索引 下面的索引 上面 下面等等 我不希望它环绕 而是停止并继续朝未探索的方向前进 所以我的例子中索引的顺序是 5 6 4 7 3 8 2 9
  • 神经网络特征提取

    我正在使用神经网络进行字母和数字的简单识别 到目前为止 我使用字母图像的每个像素作为网络的输入 不用说 这种方法产生的网络非常大 所以我想从图像中提取特征并将它们用作神经网络的输入 我的第一个问题是字母的哪些属性有利于识别它们 第二个问题是
  • 将PC添加到域并同时更改名称的问题

    我正在尝试简化将 PC 添加到域的过程 到目前为止 我可以更改 PC 名称 重新启动并将 PC 添加到特定 OU 然后再次重新启动 我和OP有同样的问题这个话题 https stackoverflow com questions 62177
  • 具有泛型构造函数的泛型类? [复制]

    这个问题在这里已经有答案了 我有一个通用类 构造函数需要接受一个参数 该参数是同一类的另一个实例 问题是另一个实例可以具有不同的泛型类型 看起来 C 允许我拥有一个具有自己的泛型类型的方法 但这对于构造函数来说似乎是不允许的 public
  • SwiftUI TextField 货币格式问题

    我在使用 TextField 输入货币金额时遇到了 SwiftUI 最终用户的可用性问题 绑定字段是双精度型 初始设置为 0 当显示文本字段时 提示为 0 00 问题是 当用户想要输入一个值时 他们必须手动使用退格键删除 0 00 另外 如
  • Oracle XE查询日志

    在 Postgres 中 您可以打开查询日志记录 从而生成一个包含任何客户端发出的所有查询的文件 Oracle XE 中是否有类似的可能性 如何打开它以及在哪里可以找到生成的文件 你会 更改会话设置 sql trace true 跟踪文件将
  • 为本机 iOS 应用程序创建 Jitsi Meet 框架并集成到 Xcode 项目中

    我已经从 Jitsi meet 网站和 git repo 检查了详细信息 以在本机应用程序中实现它 执行构建命令后 我无法在提到的位置找到框架 我也无法识别符号位置 如建议的那样 如何获取需要包含在本机应用程序中的框架 以使 jitsi m
  • 带声音的图像按钮不起作用

    我在android studio中制作了一个程序 其中有10个图像按钮 每个图像按钮单击时都会产生声音 但是 当我在模拟器上运行它们时 只有前 7 个图像按钮会发出声音 不在乎我单击的按钮的顺序 我对此很陌生 请帮助我 这是我的代码 pub
  • 如何在 ASP.NET 中找到当前页面的(文件)名称?

    如何在后面的代码中找到 default aspx 当前页面或Web控件的名称 我想编写一个使用这个名称的超类 你的意思是你想找到当前执行的对象的原始文件名 即 从您想要检索的控件 MyControl 内部MyControlOnDisk as
  • pythonunittestassertCountEqual使用'is'而不是'=='?

    我正在尝试使用 python 的unittest库来编写一些单元测试 我有一个返回对象的无序列表的函数 我想验证对象是否相同 并且我正在尝试使用断言计数等于 http docs python org py3k library unittes
  • 如何通过客户端 Java 代码获取 Google Web Toolkit 中的当前 URL?

    我试图读取 URL 的查询参数 https stackoverflow com questions 4514940 reading request parameters in google app engine with java在客户端
  • 处理 NULL 的最佳方法

    在我的函数顶部 我正在尝试用最好的方法来处理 C 中进入我的程序的 null 值 检查和处理空值的最佳方法是什么 为什么 我已经添加了我现在正在使用的完整代码 Resharper 告诉我使用选项 1 通常我会按照它所说的去做 因为我明白为什
  • 使用 JS 强制页面缩放至 100%

    我在 Canvas 中创建了一个小游戏 但遇到了问题 某些将默认缩放设置为 100 以外的用户无法看到整个游戏页面 我尝试过使用这个CSS zoom 100 这个 HTML 还有这个JS style zoom 75 有什么想法如何以编程方式
  • React Redux:获取 Props 并更新状态

    我是第一次尝试 React Redux JS 我对在组件中设置状态与让 redux 更新它有点困惑 我想单击一个按钮将 lightOn 设置为 true 并显示更新的 this props lightOn 值 我错过了一些基本的东西 但不确
  • JsonConverter如何反序列化为通用对象

    我通过 webapi 发送这个结构 DataContract public class PacketData public enum Opcodes Hello 0x00 Close 0x01 Serial 0x02 GPIO 0x04 D