我有一个类,它有一个默认构造函数,还有一个重载构造函数,它接受一组参数.这些参数与对象上的字段匹配,并在构造时指定.此时,我需要默认构造函数用于其他目的,所以如果可以的话,我想保留它.

我的问题是:如果我删除默认构造函数并传入JSON字符串,对象将正确反序列化并传入构造函数参数,而不会出现任何问题.我最终以我预期的方式取回了这个物体.然而,只要我将默认构造函数添加到对象中,当我调用JsonConvert.DeserializeObject<Result>(jsontext)时,属性就不再填充.

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

另一个注意事项:构造函数参数确实与字段的名称完全匹配,只是参数以小写字母开头.我认为这无关紧要,因为正如我所提到的,反序列化在没有默认构造函数的情况下运行良好.

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

构造函数参数名必须与JSON对象的相应属性名匹配(忽略大小写),这一点很重要,这样才能正常工作.然而,对于对象的每个属性,您不一定都必须有一个构造函数参数.对于构造函数参数未涵盖的JSON对象属性,JSON.Net将try 使用公共属性访问器(或标记为[JsonProperty]的属性/字段)在构建对象后填充该对象.

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相关问答推荐

中间初始化的Jolt配置

Vega Lite中的图例对齐

使用PowerShell解析文件并获取特定行的值

合并2个嵌套词典

使用jq过滤复杂json对象中的数据

将 REST API - json 输出转换为表 Power BI

如何使用 serde_json 构建有状态的流式解析器?

如何使用 Google 表格应用程序脚本将 JSON 中的多个字段提取到 Google 表格中

派生类的属性没有得到价值

JSON 模式实际用于什么目的?

在 rust 中从 API 反序列化 serde_json

如何从 JSON 对象中获取日期

json.dumps 打乱了顺序

在 JavaScript 中从 Json 数据中删除反斜杠

如何将 LinkedTreeMap 转换为 gson JsonObject

android - 在 adb logcat 输出中格式化 json 字符串

使用绝对或相对路径在 curl 请求中发送 json 文件

在android中读取Json数组

PHP json_encode json_decode UTF-8

你如何在 Arrays of Arrays 上 OPENJSON