JamesNK / Newtonsoft.Json

Json.NET is a popular high-performance JSON framework for .NET
https://www.newtonsoft.com/json
MIT License
10.81k stars 3.26k forks source link

$ref does not work if $id is not first property (even if readahead is set) #2398

Open jogibear9988 opened 4 years ago

jogibear9988 commented 4 years ago

Source/destination types

        public static Newtonsoft.Json.JsonSerializerSettings JsonNetDefaultSettings = new Newtonsoft.Json.JsonSerializerSettings()
        {
            TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto,
            MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead
            PreserveReferencesHandling = PreserveReferencesHandling.Objects,
            Converters = new List<JsonConverter>() {new IpAddressConverter()}
        };

Source/destination JSON

{
   "$id":"1",
   "$type":"MCC.ActionSystem.ActionTasks.Common.Flow.Decision.DecisionActionTaskDTO, MCC.ActionSystem",
   "Condition":{
      "Value1":{
         "ValueType":"Property",
         "Value":null,
         "$id":"3"
      },
      "Value2":{
         "ValueType":"Const",
         "Value":null,
         "$id":"4"
      },
      "ComparisonMode":"IsNull",
      "IsNegated":false,
      "$id":"2"
   },
   "TrueActionTask":{
      "$type":"MCC.ActionSystem.ActionTasks.Common.ChangeField.ChangeFieldActionTaskDTO, MCC.ActionSystem",
      "Field":{
         "ValueType":"Property",
         "Value":null,
         "$id":"6"
      },
      "Value":{
         "ValueType":"Const",
         "Value":null,
         "$id":"7"
      },
      "ChangeFieldType":0,
      "ApplyChangesImmediately":false,
      "AutomaticlyCreateInstancesOfParentObjects":false,
      "ConvertSourceValueToTargetType":false,
      "NextActionTask":{
         "$type":"MCC.ActionSystem.ActionTasks.Common.Information.Description.DescriptionActionTaskDTO, MCC.ActionSystem",
         "Message":{
            "ValueType":"Const",
            "Value":null,
            "$id":"9"
         },
         "NextActionTask":null,
         "ConfiguratorPosition":{
            "X":115,
            "Y":385,
            "Width":200,
            "Height":100,
            "Z":0,
            "Layer":0,
            "$id":"10"
         },
         "Comment":null,
         "Id":"6b2295ae-e5a2-4080-81d0-077bd9ee39ed",
         "$id":"8"
      },
      "ConfiguratorPosition":{
         "X":580,
         "Y":365,
         "Width":200,
         "Height":100,
         "Z":0,
         "Layer":0,
         "$id":"11"
      },
      "Comment":null,
      "Id":"53397d02-cb40-46c1-affd-167d39a4921a",
      "$id":"5"
   },
   "FalseActionTask":{
      "$type":"MCC.MFCV2.Services.TransportService2Interfaces.Actions.ChangeResourceTypeActionTaskDTO, MCC.MFCV2.Services.TransportService2Interfaces",
      "Value":{
         "ValueType":"Const",
         "Value":null,
         "$id":"13"
      },
      "NextActionTask":{
         "$ref":"5"
      },
      "ConfiguratorPosition":{
         "X":657,
         "Y":103,
         "Width":200,
         "Height":100,
         "Z":0,
         "Layer":0,
         "$id":"14"
      },
      "Comment":null,
      "Id":"456de253-0900-489c-a565-e1fd437506e1",
      "$id":"12"
   },
   "ConfiguratorPosition":{
      "X":182,
      "Y":174,
      "Width":200,
      "Height":100,
      "Z":0,
      "Layer":0,
      "$id":"15"
   },
   "Comment":null,
   "Id":"d20bc27f-cd27-4623-83ad-fc489e67dcc8"
}

Expected behavior

References should work

Actual behavior

References do not work

jogibear9988 commented 4 years ago

If I move the "$id" to the beginning, it works

BramVader commented 2 months ago

Never too late to respond to an old issue... MetadataPropertyHandling.ReadAhead only applies to the order of properties within an object, not to the order of objects within the document. Meaning that your $id, $ref, etc. must come first in an object unless MetadataPropertyHandling.ReadAhead is set. As far as I know, it's not possible to have $id further in the document than the matching $ref.