JSON десериализация не десериализация $ ref свойство - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь десериализовать после JSON (упрощенно), чтобы указать на проблему. SampleRuleSet теряет Parent, используя информацию $ ref, тогда как он существует в JSON, и интересен для всех дочерних элементов, находящихся под SampleRuleSet, которые имеют информацию о Parent после десериализации.

Это очень странное поведение, с которым я столкнулся, и мои исследования не привели меня к какому-либо конкретному решению. Однако я думаю, что это происходит из-за упорядочения элементов, для которых я использовал класс OrderedContractResolver из следующего post , но проблема все еще существует.

{
  "$id": "119",
  "$type": "FSX.Client.Entities.RuleFolder, FSX.Client.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
  "Children": [
    {
      "$id": "120",
      "$type": "FSX.Client.Entities.RuleSet, FSX.Client.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
      "Children": [
        {
          "$id": "121",
          "$type": "FSX.Client.Entities.SetValue, FSX.Client.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
          "Id": "d835028e-f630-42fa-b77d-af1b8abbc7a3",
          "Name": "iterator",
          "Parent": {
            "$ref": "120"
          }
        },        
        {
          "$id": "138",
          "$type": "FSX.Client.Entities.SetValue, FSX.Client.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
          "Id": "0101075c-c9dc-4f9d-9681-c72cc278e69f",
          "Name": "Set_pvFv",
          "Parent": {
            "$ref": "120"
          }
        }        
      ],
      "Id": "b87ee6b6-a461-4669-bfce-31d5ed821458",
      "Name": "SampleRuleSet",
      "Parent": {
        "$ref": "119"
      }
    }
  ],
  "Id": "5d950d31-1eec-4beb-ab11-21c20b183f81",
  "Name": "Financial",
  "Parent": null
}

Ниже приведены мои настройки API служб:

services.AddControllersWithViews()
    .AddNewtonsoftJson(options =>
        {
            options.SerializerSettings.ContractResolver = new OrderedContractResolver();
            options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
            options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
            options.SerializerSettings.TypeNameHandling = TypeNameHandling.Objects;
            options.SerializerSettings.TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Full;
        }
    );

И у меня аналогичные настройки в конце потребления.

Классы:

[DataContract]
public abstract class GenericRule : ClientEntity
{
    protected GenericRule() : this(null) { }

    protected GenericRule(string name)
    {
        Name = name;
    }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public ContainerRule Parent { get; set; }
}

[DataContract]
public abstract class ContainerRule : GenericRule
{
    [DataMember(Name = nameof(Children))]
    protected ObservableCollection<GenericRule> _children =
        new ObservableCollection<GenericRule>();
    public IEnumerable<GenericRule> Children => _children.AsEnumerable();
}

[DataContract]
public abstract class ActionRule : GenericRule { }

[DataContract]
public class Entity : ClientEntity { }

[DataContract]
public class RuleFolder : ContainerRule 
{ 
    private RuleFolder() { }
    public RuleFolder(Entity entity) { } // the only way to construct this object is by using this ctor
}

[DataContract]
public class RuleSet : ContainerRule { }

[DataContract]
public class SetValue : ActionRule { }

Важным моментом является то, что я не украсил ни одно из своих свойств класса [JsonProperty], они просто украшены [DataMember], и мое намерение также не украшать, поэтому я ищу решение без украшения атрибута.

...