JSON.net:如何反序列化不使用默认的构造函数? [英] JSON.net: how to deserialize without using the default constructor?

查看:230
本文介绍了JSON.net:如何反序列化不使用默认的构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有了一个默认的构造函数,也是一个重载的构造函数的一组参数的类。这些参数相匹配的对象的字段和在建筑分配。在这一点上,我需要作其他用途的默认构造函数,所以我想保持它,如果我可以。

我的问题:如果我删除默认的构造函数,并传入JSON字符串,对象正确进行反序列化,并通过在构造函数中的参数没有任何问题。我最终取回填充我希望的方式的对象。然而,当我添加默认的构造函数到对象,当我打电话 JsonConvert.DeserializeObject<结果>(jsontext)的属性不再填充

在这一点上我已经尝试添加新JsonSerializerSettings(){CheckAdditionalContent =真} 来反序列化的呼叫。那什么也没做。

另外要注意的。该构造器的参数都匹配字段的名称一致,除了这些参数是开始一个小写字母。我不认为这会事,因为,就像我提到的,反序列化工作正常,没有默认构造函数。

下面是我的构造函数的示例:

 公开结果(){}    公开结果(INT code,字符串格式,字典<字符串,字符串>细节= NULL)
    {
        code = code? ERROR_ code;
        格式=格式;        如果(详情== NULL)
            详细=新词典<字符串,字符串>();
        其他
            详情=细节;
    }


解决方案

Json.Net prefers使用默认(无参数)构造一个对象(如果有)。如果有多个构造函数,你想Json.Net使用非默认的一个,那么你可以在 [JsonConstructor] 属性添加到您想要的构造Json.Net打电话。

  [JsonConstructor]
公开结果(INT code,字符串格式,字典<字符串,字符串>细节= NULL)
{
    ...
}

这是非常重要的构造函数的参数名称相匹配的JSON对象,这样才能正常工作,相应的属性名称。你不一定必须有对于对象的每个属性的构造参数,但是。对于未覆盖的构造函数的参数的JSON对象属性,Json.Net将尝试使用公共属性访问器(或属性/标记域 [JsonProperty] )以建设后填充对象。

如果您不想属性添加到您的类或不以其他方式控制源$ C ​​$ C您试图反序列化类,那么另一种选择是创建一个自定义的<一个href=\"http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonConverter.htm\">JsonConverter实例化和填充你的对象。例如:

 类ResultConverter:JsonConverter
{
    公众覆盖布尔CanConvert(类型的objectType)
    {
        返回(==的objectType typeof运算(结果));
    }    公众覆盖对象ReadJson(JsonReader读者,类型的objectType,对象existingValue,JsonSerializer串行)
    {
        //加载JSON的结果变成JObject
        JObject祚= JObject.Load(读卡器);        //读取将被用作构造参数的属性
        诠释? code =(INT?)祚[code];
        字符串格式=(字符串)祚[格式];        //使用非默认构造函数构造Result对象
        结果结果=新的结果(code,格式);        //(如果什么都需要结果对象上进行填充,这样做在这里)        //返回结果
        返回结果;
    }    公众覆盖布尔CanWrite
    {
        获得{返回false; }
    }    公共覆盖无效WriteJson(JsonWriter作家,对象的值,JsonSerializer串行)
    {
        抛出新NotImplementedException();
    }
}

然后,转换器添加到您的序列化的设置,当你反序列化使用的设置:

  JsonSerializerSettings设置=新JsonSerializerSettings();
settings.Converters.Add(新ResultConverter());
结果结果= JsonConvert.DeserializeObject&LT;结果&GT;(jsontext,设置);

I have a class that has a default constructor and also an overloaded constructor that takes in a set of parameters. These parameters match to fields on the object and are assigned on construction. At this point i need the default constructor for other purposes so i would like to keep it if i can.

My Problem: If I remove the default constructor and pass in the JSON string, the object deserializes correctly and passes in the constructor parameters without any issues. I end up getting back the object populated the way I would expect. However, as soon as I add the default constructor into the object, when i call JsonConvert.DeserializeObject<Result>(jsontext) the properties are no longer populated.

At this point I have tried adding new JsonSerializerSettings(){CheckAdditionalContent = true} to the deserialization call. that did not do anything.

Another note. the contructor parameters do match the names of the fields exactly except that the parameters are start with a lowercase letter. I wouldn't think this would matter since, like i mentioned, the deserialization works fine with no default constructor.

Here is a sample of my constructors:

    public Result() { }

    public Result(int? code, string format, Dictionary<string, string> details = null)
    {
        Code = code ?? ERROR_CODE;
        Format = format;

        if (details == null)
            Details = new Dictionary<string, string>();
        else
            Details = details;
    }

解决方案

Json.Net prefers to use the default (parameterless) constructor on an object if there is one. If there are multiple constructors and you want Json.Net to use a non-default one, then you can add the [JsonConstructor] attribute to the constructor that you want Json.Net to call.

[JsonConstructor]
public Result(int? code, string format, Dictionary<string, string> details = null)
{
    ...
}

It is important that the constructor parameter names match the corresponding property names of the JSON object for this to work correctly. You do not necessarily have to have a constructor parameter for every property of the object, however. For those JSON object properties that are not covered by the constructor parameters, Json.Net will try to use the public property accessors (or properties/fields marked with [JsonProperty]) to populate the object after constructing it.

If you do not want to add attributes to your class or don't otherwise control the source code for the class you are trying to deserialize, then another alternative is to create a custom JsonConverter to instantiate and populate your object. For example:

class ResultConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Result));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // Load the JSON for the Result into a JObject
        JObject jo = JObject.Load(reader);

        // Read the properties which will be used as constructor parameters
        int? code = (int?)jo["Code"];
        string format = (string)jo["Format"];

        // Construct the Result object using the non-default constructor
        Result result = new Result(code, format);

        // (If anything else needs to be populated on the result object, do that here)

        // Return the result
        return result;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Then, add the converter to your serializer settings, and use the settings when you deserialize:

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new ResultConverter());
Result result = JsonConvert.DeserializeObject<Result>(jsontext, settings);

这篇关于JSON.net:如何反序列化不使用默认的构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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