问题描述
我有一个类,它有一个默认构造函数和一个接受一组参数的重载构造函数.这些参数与对象上的字段匹配并在构造时分配.在这一点上,我需要将默认构造函数用于其他目的,所以如果可以的话,我想保留它.
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.
我的问题:如果我删除默认构造函数并传入 JSON 字符串,则对象会正确反序列化并传入构造函数参数而不会出现任何问题.我最终以我期望的方式取回了填充的对象.但是,一旦我将默认构造函数添加到对象中,当我调用 JsonConvert.DeserializeObject(jsontext)
时,不再填充属性.
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.
此时我已尝试将 new JsonSerializerSettings(){CheckAdditionalContent = true}
添加到反序列化调用中.那没有做任何事情.
At this point I have tried adding new JsonSerializerSettings(){CheckAdditionalContent = true}
to the deserialization call. That did not do anything.
另一个注意事项:构造函数参数确实与字段的名称完全匹配,只是参数以小写字母开头.我认为这无关紧要,因为就像我提到的,反序列化在没有默认构造函数的情况下工作正常.
Another note: the constructor 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 更喜欢在对象上使用默认(无参数)构造函数(如果有的话).如果有多个构造函数并且您希望 Json.Net 使用非默认构造函数,那么您可以将 [JsonConstructor]
属性添加到您希望 Json.Net 调用的构造函数中.
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)
{
...
}
构造函数参数名称与 JSON 对象的相应属性名称匹配(忽略大小写)很重要,这样才能正常工作.但是,您不一定必须为对象的每个属性都有一个构造函数参数.对于那些没有被构造函数参数覆盖的 JSON 对象属性,Json.Net 会尝试使用公共属性访问器(或标记为 [JsonProperty]
的属性/字段)来填充对象..
It is important that the constructor parameter names match the corresponding property names of the JSON object (ignoring case) 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.
如果您不想向类添加属性,或者不想以其他方式控制要反序列化的类的源代码,则另一种选择是创建自定义 JsonConverter 来实例化和填充您的对象.例如:
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:如何在不使用默认构造函数的情况下反序列化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!