Json.Net JsonConvert.SerializeObject json格式不正确。

3
我将使用最新版本(6.0.6)的Json.net来序列化一个对象,但我认为结果不正确。
下面是C#示例的结果:
"Key":"AAA","No":"BBB","Project_No":"CCC","Resource_No":"DDD","Resource_Group_No":"EEE","Stadium_Code":"FFF","Entry_NoSpecified":false,"Line_NoSpecified":false,"Execution_DateSpecified":false,"HoursSpecified":false,"ExecutedSpecified":false,"FixedSpecified":false,"ConfirmedSpecified":false,"Begin_TimeSpecified":false,"Updated_TimeSpecified":false

正如您所见,所有非字符串属性都不会被序列化,例如Entry_No、Line_No、Hours和日期。

这是Json.Net的一个bug吗?

用于重现问题的代码如下:

using System;
using Newtonsoft.Json;

namespace JSONNET
{
    class Program
    {
        static void Main(string[] args)
        {
            var dto = new ProjectPlanningEntryDto()
            {
                Key = "AAA",
                No = "BBB",
                Entry_No = 123,
                Project_No = "CCC",
                Line_No = 456,
                Resource_No = "DDD",
                Resource_Group_No = "EEE",
                Execution_Date = DateTime.Now,
                Hours = 4,
                Begin_Time = DateTime.Now,
                Updated_Time = DateTime.Now,
                Stadium_Code = "FFF"
            };

            var json = JsonConvert.SerializeObject(dto);

            Console.WriteLine(json);
            Console.ReadLine();
        }
    }

    public class ProjectPlanningEntryDto
    {
        public string Key { get; set; }
        public string No { get; set; }
        public int Entry_No { get; set; }
        public string Project_No { get; set; }
        public int Line_No { get; set; }
        public string Resource_No { get; set; }
        public string Resource_Group_No { get; set; }
        public DateTime Execution_Date { get; set; }
        public decimal Hours { get; set; }
        public bool Executed { get; set; }
        public bool Fixed { get; set; }
        public bool Confirmed { get; set; }
        public DateTime Begin_Time { get; set; }
        public DateTime Updated_Time { get; set; }
        public string Stadium_Code { get; set; }
        public bool Entry_NoSpecified { get; set; }
        public bool Line_NoSpecified { get; set; }
        public bool Execution_DateSpecified { get; set; }
        public bool HoursSpecified { get; set; }
        public bool ExecutedSpecified { get; set; }
        public bool FixedSpecified { get; set; }
        public bool ConfirmedSpecified { get; set; }
        public bool Begin_TimeSpecified { get; set; }
        public bool Updated_TimeSpecified { get; set; }
    }
}

1
如果将Entry_NoSpecified设置为true会发生什么? - J. Steen
如果我将Entry_NoSpecified设置为true,那么Entry_No字段就会被序列化。这意味着Specified属性会调用我不知道的特殊行为? - Tomd
1
在2011年1月的第4版中,他们添加了XmlSerializer样式的Specified属性支持。你可以在这些发布说明中发现它:http://james.newtonking.com/archive/2011/01/03/json-net-4-0-release-1-net-4-and-windows-phone-support - J. Steen
2个回答

3

根据第4版发布博客,Json.NET似乎遵守了拥有<Name>Specified属性的约定,以决定是否序列化属性。因此,

var dto = new ProjectPlanningEntryDto()
{
    Key = "AAA",
    No = "BBB",
    Entry_No = 123,
    Entry_NoSpecified = true,
    Project_No = "CCC",
    Line_No = 456,
    Line_NoSpecified = true,
    ...
};

这将产生您想要的json对象。这种约定的应用方式与XmlSerializer相同,详见此处:MSDN: System.Xml.Serialization.XmlSerializer

Another option is to use a special pattern to create a Boolean field recognized by the XmlSerializer, and to apply the XmlIgnoreAttribute to the field. The pattern is created in the form of propertyNameSpecified. For example, if there is a field named "MyFirstName" you would also create a field named "MyFirstNameSpecified" that instructs the XmlSerializer whether to generate the XML element named "MyFirstName". This is shown in the following example.

public class OptionalOrder
{
    // This field should not be serialized 
    // if it is uninitialized.
    public string FirstOrder;

    // Use the XmlIgnoreAttribute to ignore the 
    // special field named "FirstOrderSpecified".
    [System.Xml.Serialization.XmlIgnoreAttribute]
    public bool FirstOrderSpecified;
}
为了应用相同的逻辑 - 并且不在json中序列化<Name>Specified属性 - 只需使用JsonIgnoreAttribute来修饰这些属性即可。

你能简要解释一下什么是指定属性吗?我在谷歌上搜索不到相关信息 :( - t3chb0t
@t3chb0t 添加了一些进一步的信息。希望这能澄清事情。我知道在谷歌上搜索“specified”有点困难,因为我甚至要做很多工作才能找到关于Json.NET的信息。;) - J. Steen

0

这一定是JSON.NET中的一个bug,因为当我从DateTime属性中删除了下划线时,它们被正确序列化了。


是的,因为那样你就没有匹配的指定属性。所以,不是一个错误。 - J. Steen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接