Json.NET - 反序列化接口属性引发错误“类型是接口或抽象类,无法实例化”

2024-05-18

我有一个类,其属性是接口。

public class Foo
{ 
    public int Number { get; set; }

    public ISomething Thing { get; set; }
} 

尝试反序列化Foo使用 Json.NET 的类给我一条错误消息,例如:

Could not create an instance of type ISomething. Type is an interface or abstract class and cannot be instantiated.

来自类似的question https://stackoverflow.com/questions/2254872/using-json-net-converters-to-deserialize-properties,我可以看到使用TypeNameHandling = TypeNameHandling.Objects将通过允许 Json.NET 在序列化时包含 .NET 类型名称来解决该错误,从而了解随后需要将对象反序列化为哪种具体类型。

不过,似乎有建议谨慎 https://www.newtonsoft.com/json/help/html/SerializationSettings.htm#TypeNameHandling当使用一个TypeNameHandling值以外的值TypeNameHandling.None从外部源反序列化 JSON。

TypeNameHandling.Objects显然属于这一类。

有没有一种方法可以在不引入任何安全风险的情况下反序列化具体对象类型(实现接口)?


考虑到您没有字段来确定要转换为哪种具体类型,您唯一的解决方案就是您所说的,TypeNameHandling = TypeNameHandling.Objects.

但是,您可以减轻安全漏洞。

使用自定义ISerializationBinder https://www.newtonsoft.com/json/help/html/SerializationSettings.htm#SerializationBinder在序列化期间将 .NET 类型解析为类型名称以及反序列化期间将类型名称解析为 .NET 类型时验证传入类型名称:

ConsoleAppSerializationBinder.cs

public class ConsoleAppSerializationBinder : ISerializationBinder
{
    public Type BindToType(string? assemblyName, string typeName)
    {
        var resolvedTypeName = $"{typeName}, {assemblyName}";
        return Type.GetType(resolvedTypeName, true);
    }

    public void BindToName(Type serializedType, out string? assemblyName, out string? typeName)
    {
        assemblyName = null;
        typeName = serializedType.AssemblyQualifiedName;
    }
}

Set the SerializationBinder您的财产JsonSerializerSettings object https://www.newtonsoft.com/json/help/html/SerializationSettings.htm到绑定器的实例,并使用与最初反序列化数据相同类型的绑定器进行反序列化。

var jsonSerializerSettings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Objects,
    SerializationBinder = new ConsoleAppSerializationBinder()
};

这是一些演示工作代码来演示用法:

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var jsonSerializerSettings = new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.Objects,
                SerializationBinder = new ConsoleAppSerializationBinder()
            };

            var something1Input = new Foo
            {
                Number = 1,
                Thing = new Something1
                {
                    RandomNumber = 1,
                    RandomString = "test"
                }
            };

            var something2Input = new Foo
            {
                Number = 1,
                Thing = new Something2
                {
                    RandomNumber = 2,
                    RandomBool = true
                }
            };

            var something1Json = JsonConvert.SerializeObject(something1Input, jsonSerializerSettings);
            var something2Json = JsonConvert.SerializeObject(something2Input, jsonSerializerSettings);

            var something1 = JsonConvert.DeserializeObject<Foo>(something1Json, jsonSerializerSettings);
            var something2 = JsonConvert.DeserializeObject<Foo>(something2Json, jsonSerializerSettings);

            Console.WriteLine(something1.Thing.GetType());
            Console.WriteLine(something2.Thing.GetType());
        }

        public class Foo
        {
            public int Number { get; set; }

            public ISomething Thing { get; set; }
        }

        public interface ISomething
        {
            public int RandomNumber { get; set; }
        }

        public class Something1 : ISomething
        {
            public int RandomNumber { get; set; }
            public string RandomString { get; set; }
        }

        public class Something2 : ISomething
        {
            public int RandomNumber { get; set; }
            public bool RandomBool { get; set; }
        }

        public class ConsoleAppSerializationBinder : ISerializationBinder
        {
            public Type BindToType(string? assemblyName, string typeName)
            {
                var resolvedTypeName = $"{typeName}, {assemblyName}";
                return Type.GetType(resolvedTypeName, true);
            }

            public void BindToName(Type serializedType, out string? assemblyName, out string? typeName)
            {
                assemblyName = null;
                typeName = serializedType.AssemblyQualifiedName;
            }
        }
    }
}

Output:

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

Json.NET - 反序列化接口属性引发错误“类型是接口或抽象类,无法实例化” 的相关文章

  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • 将多个表映射到实体框架中的单个实体类

    我正在开发一个旧数据库 该数据库有 2 个具有 1 1 关系的表 目前 我为每个定义的表定义了一种类型 1Test 1Result 我想将这些特定的表合并到一个类中 当前的类型如下所示 public class Result public
  • 重载<<的返回值

    include
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • IEnumerable 与 IReadOnlyList

    选择有什么区别IEnumerable
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • 覆盖子类中的字段或属性

    我有一个抽象基类 我想声明一个字段或属性 该字段或属性在从该父类继承的每个类中具有不同的值 我想在基类中定义它 以便我可以在基类方法中引用它 例如覆盖 ToString 来表示 此对象的类型为 property field 我有三种方法可以
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低

随机推荐

  • PostgreSQL - 致命:用户“myuser”身份验证失败[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我刚刚在我的 Ubuntu Box 中安装了 PostGreSQL 我想做的第一件事就是创建一个数据库 我读了文档 http www postgres
  • HTML 代码中的 PHP [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我用 HTML 代码编写了 PHP div div 但这出现在输出页面中 else print 我怎样才能让PHP执行 你的文件有一个 p
  • 如何使用 window.onerror 捕获所有 javascript 错误? (包括道场)

    这个问题是后续问题javascript 如何在弹出警报中显示脚本错误 https stackoverflow com questions 2604976 javascript how to display script errors in
  • 如何将图像和 POST 数据上传到 Azure 移动服务 ApiController 终结点?

    我正在尝试上传图片and POST表单数据 尽管理想情况下我希望它是json 到我的端点Azure 移动服务应用 我有ApiController method HttpPost Route api upload databaseId sea
  • 当实体的主键之间存在关系时,必须在调用 save() 之前手动分配此类的 ids

    我有两个实体 我想在它们之间创建一个关系 以便它们共享它们的主键 当我们提交一个实体时 另一个实体也应该使用为第一个实体生成的相同主键来提交 我的第一个实体是用户 Entity Table name ENDUSER public class
  • Activity 类型中的方法 showDialog(int) 在 Android 中已被弃用?

    方法showDialog int 从类型Activity is 已弃用 什么原因 以及如何解决 什么原因 http developer android com reference android app Activity html show
  • 模板中带有 ng-if 的 angularjs 指令

    我正在构建一个在模板内使用 ng if 的指令 奇怪的是 提供给链接函数的元素没有扩展ng if代码 它只是ng if的注释行 经过一番尝试 我发现通过将链接代码包装在 timeout 中似乎可以使其正常工作 但我想知道这是否不是正确的处理
  • Nginx docker容器代理传递到另一个端口

    我想在 docker 容器中运行 Nginx 它监听端口 80 并且当 url 以 word 开头时 我希望它 proxy pass 到端口 8080api 我有一些网络应用程序侦听端口 8080 这在没有 docker 的情况下对我来说一
  • C#:如何防止主窗体过早显示

    在我的 main 方法中 我像往常一样启动主窗体 Application EnableVisualStyles Application SetCompatibleTextRenderingDefault false Application
  • Bigquery - 选择时间戳作为人类可读的日期时间

    如何在 Google Bigquery 中选择时间戳 存储为秒 作为人类可读的日期时间 schema id STRING signup date TIMESTAMP 我使用编写了一个查询DATE功能 但出现错误 SELECT DATE cr
  • 使用多个值过滤 JFX TableView

    我目前正在尝试过滤我的数据TableView using FilteredList with predicate 我有2个ComboBoxes来过滤值 我的表包含Result Each Result has a Student that S
  • 如何在Java媒体框架中学习.wav持续时间?

    我正在尝试使用 java 媒体框架将 mov 文件与 wav 文件合并 因此我需要知道它们的持续时间 我怎样才能做到这一点 任何想法 将不胜感激 您可以使用以下方式了解声音文件的持续时间 即 VitalyVal 的第二种方式 import
  • 将目录压缩为单个文件的方法有哪些

    不知道怎么问 所以我会解释一下情况 我需要存储一些压缩文件 最初的想法是创建一个文件夹并存储所需数量的压缩文件 并创建一个文件来保存有关每个压缩文件的数据 但是 我不被允许创建许多文件 只能有一个 我决定创建一个压缩文件 其中包含有关进一步
  • Excel:#CALC!使用 MAP 函数计算间隔重叠时出现错误(嵌套数组)

    我正在努力解决以下公式 它适用于某些情况 但不适用于所有情况 名字input有失败的数据集 得到一个 CALC 描述 嵌套数组 错误 LET input N1 0 0 N1 0 10 N1 10 20 names INDEX input 1
  • 在.rdlc报告的底部设置一个文本框

    我在 rdlc 报告中使用 tablix 有一个文本框 其中包含文本 签名 我想将此文本框放置在报告最后一页的底部 就在页脚之前 我已经用谷歌搜索了这个解决方案 但没有找到满意的结果 我的环境是VS2010 framework 4 0 有什
  • 内嵌显示定义术语和描述

    我正在为页面上的某些元素使用定义列表 并需要它们内联显示 例如 它们normally看起来像 我需要它们看起来像 注意多个 DD 我可以让它们在 moz 中使用 float 来正常工作 但无论我尝试什么 它们都无法在 IE 中工作 我通常会
  • C 预处理器库

    我的任务是开发源分析工具C程序 并且我需要在分析本身之前预处理代码 我想知道什么是最好的图书馆 我需要一些重量轻 便于携带的东西 与其推出自己的 为什么不使用cpp这是的一部分gcc suite http gcc gnu org onlin
  • 索引后文件被锁定

    我的 网络 应用程序中有以下工作流程 从存档下载 pdf 文件 索引文件 删除文件 我的问题是 对文件进行索引后 它仍然处于锁定状态 并且删除部分会引发异常 这是我用于索引文件的代码片段 try ContentStreamUpdateReq
  • 如何使用 pybrain 黑盒优化训练神经网络来处理监督数据集?

    我玩了一下 pybrain 了解如何生成具有自定义架构的神经网络 并使用反向传播算法将它们训练为监督数据集 然而 我对优化算法以及任务 学习代理和环境的概念感到困惑 例如 我将如何实现一个神经网络 例如 1 以使用 pybrain 遗传算法
  • Json.NET - 反序列化接口属性引发错误“类型是接口或抽象类,无法实例化”

    我有一个类 其属性是接口 public class Foo public int Number get set public ISomething Thing get set 尝试反序列化Foo使用 Json NET 的类给我一条错误消息