How to programmatically choose a constructor during deserialization?(如何在反序列化期间以编程方式选择构造函数?)
问题描述
我想反序列化一个 System.Security.Claims.Claim
对象,通过以下方式序列化:
I would like to deserialize a System.Security.Claims.Claim
object serialized in the following way:
{
"Issuer" : "LOCAL AUTHORITY",
"OriginalIssuer" : "LOCAL AUTHORITY",
"Type" : "http://my.org/ws/2015/01/identity/claims/mytype",
"Value" : "myvalue",
"ValueType" : "http://www.w3.org/2001/XMLSchema#string"
}
我得到的是一个 JsonSerializationException
:
找不到用于类型的构造函数System.Security.Claims.Claim.一个类应该有一个默认值构造函数,一个带参数的构造函数或一个标记的构造函数带有 JsonConstructor 属性.
Unable to find a constructor to use for type System.Security.Claims.Claim. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.
经过一番调查,我终于明白了上述消息中 one 的含义:JSON 反序列化程序无法找到正确的构造函数 - 在 Claim
的情况下type - 多个带参数的构造函数(尽管存在一个参数与上述属性完全匹配的构造函数).
After some investigation I finally understand the meaning of one in the above message: The JSON deserializer cannot find the right constructor as there are - in the case of the Claim
type - multiple constructors with arguments (although there exists a constructor with arguments matching exactly the above properties).
有没有办法告诉反序列化器选择哪个构造函数而不向该 mscorlib 类型添加 JsonConstructor
属性?
Is there a way to tell the deserializer which constructor to choose without adding the JsonConstructor
attribute to that mscorlib type?
Daniel Halan 用 Json 补丁解决了这个问题.NET 几年前.这些天有没有办法在不修改 Json.NET 的情况下解决这个问题?
Daniel Halan has solved this issue with a patch to Json.NET a few years ago. Is there a way to solve this without modifying Json.NET these days?
推荐答案
如果无法为目标类添加 [JsonConstructor]
属性(因为你不拥有代码),那么通常的解决方法是创建一个自定义 JsonConverter
正如@James Thorpe 在评论中所建议的那样.这很简单.您可以将 JSON 加载到 JObject
中,然后从中挑选各个属性来实例化您的 Claim
实例.这是您需要的代码:
If it is not possible to add a [JsonConstructor]
attribute to the target class (because you don't own the code), then the usual workaround is to create a custom JsonConverter
as was suggested by @James Thorpe in the comments. It is pretty straightforward. You can load the JSON into a JObject
, then pick the individual properties out of it to instantiate your Claim
instance. Here is the code you would need:
class ClaimConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(System.Security.Claims.Claim));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
string type = (string)jo["Type"];
string value = (string)jo["Value"];
string valueType = (string)jo["ValueType"];
string issuer = (string)jo["Issuer"];
string originalIssuer = (string)jo["OriginalIssuer"];
return new Claim(type, value, valueType, issuer, originalIssuer);
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
要使用转换器,只需将它的一个实例传递给 JsonConvert.DeserializeObject
方法调用:
To use the converter, simply pass an instance of it to the JsonConvert.DeserializeObject<T>()
method call:
Claim claim = JsonConvert.DeserializeObject<Claim>(json, new ClaimConverter());
小提琴:https://dotnetfiddle.net/7LjgGR
这篇关于如何在反序列化期间以编程方式选择构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何在反序列化期间以编程方式选择构造函数?
基础教程推荐
- c# Math.Sqrt 实现 2022-01-01
- 为什么Flurl.Http DownloadFileAsync/Http客户端GetAsync需要 2022-09-30
- SSE 浮点算术是否可重现? 2022-01-01
- 如何激活MC67中的红灯 2022-01-01
- MS Visual Studio .NET 的替代品 2022-01-01
- 有没有办法忽略 2GB 文件上传的 maxRequestLength 限制? 2022-01-01
- 将 XML 转换为通用列表 2022-01-01
- 将 Office 安装到 Windows 容器 (servercore:ltsc2019) 失败,错误代码为 17002 2022-01-01
- rabbitmq 的 REST API 2022-01-01
- 如何在 IDE 中获取 Xamarin Studio C# 输出? 2022-01-01