3

I use the latest version (6.0.6) of Json.net to serialize an object, and in my opinion, the result is not correct.

The result of the c# example below is this :

"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

As you can see, all non string properties are not serialized, eg Entry_No, Line_No, Hours and the dates

Is this a bug in Json.Net?

code to reproduce problem,

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; }
    }
}
3
  • 1
    And what happens if you set (for example) Entry_NoSpecified to true? Commented Nov 25, 2014 at 9:29
  • hmm, if I set Entry_NoSpecified to true, the Entry_No field is serialized. This means the Specified properties invoke special behavior I did not know off? Commented Nov 25, 2014 at 9:48
  • 1
    In version 4 (January 2011), they added XmlSerializer style Specified property support. Found it lurking inconspiculously in these release notes: james.newtonking.com/archive/2011/01/03/… Commented Nov 25, 2014 at 9:53

2 Answers 2

3

Json.NET seems to honour the convention of having <Name>Specified properties to see if it should serialize a property or not, according to the version 4 release blog post. So,

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

would result in the json object you want. This convention is applied in the same way as it applies to the XmlSerializer, as detailed here: 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;
}

To apply the same logic - and not serialize the <Name>Specified properties in json - just use the JsonIgnoreAttribute to decorate those properties.

Sign up to request clarification or add additional context in comments.

2 Comments

Could you briefly explain what a Specified Property is? I have no luck googleing for it :(
@t3chb0t Added some further info. Hope that clears things up. Googling for "specified" is kind of difficult, I know since I did a bunch of it to even find the info on Json.NET. ;)
0

This must be a bug in JSON.NET because when I removed the underscores from the DateTime properties they got serialized correctly.

1 Comment

...Yes, because then you don't have matching Specified-properties. So, no. Not a bug.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.