如何以编程方式选择反序列化过程的构造? [英] How to programmatically choose a constructor during deserialization?

查看:338
本文介绍了如何以编程方式选择反序列化过程的构造?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想反序列化以下列方式序列化 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.

经过一番调查,我终于明白意思的有一个的在上面留言:因为有JSON的解串器无法找到合适的构造 - 在索赔的情况下类型 - 多个构造带参数(虽然存在匹配上面完全相同的性能参数的构造函数)

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

时有没有办法告诉解串器哪个构造不添加 JsonConstructor 属性到mscorlib程序类型来选择?

Is there a way to tell the deserializer which constructor to choose without adding the JsonConstructor attribute to that mscorlib type?

丹尼尔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 作为被@詹姆斯·索普在评论建议。这是很简单的。您可以将JSON装载到 JObject ,然后挑选出了它的各个属性来实例要求实例。下面是你需要的代码:

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< T>()方法调用:

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

这篇关于如何以编程方式选择反序列化过程的构造?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆