JsonConvert.DeserializeObject不执行属性设置器

时间:2019-05-01 09:29:42

标签: c# json json.net

当JSON中缺少filename属性上的setter时为什么不执行?

如果不使用二传手,如何获得理想的结果?

请参见下面的简化示例:

using System;
using Newtonsoft.Json;

namespace JsonDeserializeNulls
{
    class Program
    {
        static void Main(string[] args)
        {
            var json1 = "{\r\n\t\"encoding\": \"base64\"\r\n}";
            var json2 = "{\r\n\t\"encoding\": \"base64\",\r\n\t\"filename\": null,\r\n}";

            var document1 = JsonConvert.DeserializeObject<Document>(json1);
            var document2 = JsonConvert.DeserializeObject<Document>(json2);

            Console.WriteLine(document1.ToString());
            Console.WriteLine(document2.ToString());

            Console.ReadLine();
        }
    }

    public class Document
    {
        public string Encoding { get; set; }

        private string _filename;
        public string Filename
        {
            get => _filename;
            set => _filename = string.IsNullOrEmpty(value) ? "NoFilenameSupplied" : value;
        }

        public override string ToString()
        {
            return JsonConvert.SerializeObject(this);
        }
    }
}

输出:

{"Encoding":"base64","Filename":null}

{"Encoding":"base64","Filename":"NoFilenameSupplied"}

2 个答案:

答案 0 :(得分:1)

添加默认的构造函数,并将_filename初始化为NoFilenameSupplied

编辑:

解串器将首先调用默认构造函数,将_filename设置为NoFilenameSupplied。即使JSON中缺少FileName属性,也可以确保正确设置该属性。

如果您不喜欢将支票添加到设置器中,也可以执行以下操作:

[DefaultValue("")]
[JsonProperty(NullValueHandling = NullValueHandling.Ignore,DefaultValueHandling = DefaultValueHandling.Ignore)]
public string FileName { get; set; }

如果JSON中的值为null或类型(字符串)的默认值(再次为null),这将告诉JSON.NET解串器不设置属性。我们通过使用DefaultValue属性使反序列化器认为该属性的默认值为String.Empty,而不是使null使NullValueHandlingDefaultValueHandling正常工作,来对此进行更改。

答案 1 :(得分:0)

JsonConvert不会调用setter,它只是直接将数据加载到对象中。您最好以这种方式编写它:

public class Document
{
    public string Encoding { get; set; }

    public string Filename { get; set; }

    public string SafeFilename => string.IsNullOrEmpty(Filename) ? "NoFilenameSupplied" : Filename;

    public override string ToString()
    {
        return JsonConvert.SerializeObject(this);
    }
}

现在,您可以在代码中使用SafeFilename来始终获取所需的值!