Я пытаюсь десериализовать после 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]
, и мое намерение также не украшать, поэтому я ищу решение без украшения атрибута.