我目前在使用 Newtonsoft Json 时遇到一些问题。
我想要的很简单:将要序列化的对象与所有属性和子属性进行比较以确保相等。
我现在尝试创建自己的 EqualityComparer,但它仅与父对象的属性进行比较。
另外,我尝试编写自己的ReferenceResolver,但没有成功。
让我们用一个例子来谈谈:
public class EntityA
{
int Foo {get; set;}
public override bool Equals(object obj)
{
return (obj is EntityA other) && other.Foo == this.Foo;
}
}
public class EntityB
{
int Bar {get; set;}
EntityA Parent {get; set;}
public override bool Equals(object obj)
{
return (obj is EntityB other) && other.Bar == this.Bar;
}
}
public class InnerWrapper
{
public string FooBar {get; set;}
public EntityB BEntity {get; set;}
}
public class OuterClass
{
public EntityA AEntity { get; set;}
List<InnerWrapper> InnerElements {get; set;}
}
现在我想要的是从 EntityB 到 EntityA 的引用。就我而言,它们总是一样的。所以我期望的是,在每个 EntityB 的 JSON 中,对 EntityA 的引用都写为 ref。实体的 Equal 会覆盖 Equals 以检查它们是否相同。它们是数据库对象,因此只要它们的 ID 相同,它们就相等。在这种情况下,我给他们打电话Foo
and Bar
.
我尝试过的如下:
public class MyEqualComparer : IEqualityComparer
{
public bool Equals(object x, object y)
{
return x.Equals(y);
}
public int GetHashCode(object obj)
{
return obj.GetHashCode();
}
}
具有以下 JSON 设置
public static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
NullValueHandling = NullValueHandling.Ignore,
FloatParseHandling = FloatParseHandling.Decimal,
Formatting = Formatting.Indented,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
EqualityComparer = new MyEqualComparer(),
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
Error = (sender, args) => Log.Error(args.ErrorContext.Error, $"Error while (de)serializing: {args.ErrorContext}; object: {args.CurrentObject}")
};
但这不起作用。它比较完全错误的值。例如来自的 EntityAOuterClass
与每个InnerWrapper
。但不适用于属性甚至子属性(在本例中为属性)EntityB
of the InnerWrapper
).
对于自定义的ReferenceResolver,我也没有运气,因为上面的设置确实很通用,我不知道如何编写通用的设置。
您知道如何完成这项工作吗?
// Edit:
下面是我期望的示例:
{
"$id" : "1",
"AEntity": {
"$id": "2",
"Foo": 200
},
"InnerElements": [
{
"$id": "3",
"Bar": 20,
"Parent": {
"$ref" : "2"
}
},
{
"$id": "4",
"Bar": 21,
"Parent": {
"$ref" : "2"
}
},
{
"$id": "5",
"Bar": 23,
"Parent": {
"$ref" : "2"
}
},
{
"$id": "6",
"Bar": 24,
"Parent": {
"$ref" : "2"
}
},
{
"$id": "7",
"Bar": 25,
"Parent": {
"$ref" : "2"
}
}
]
}
这就是我得到的:
{
"$id" : "1",
"AEntity": {
"$id": "2",
"Foo": 200
},
"InnerElements": [
{
"$id": "3",
"Bar": 20,
"Parent": {
"$id": "8",
"Foo": 200
}
},
{
"$id": "4",
"Bar": 21,
"Parent": {
"$id": "9",
"Foo": 200
}
},
{
"$id": "5",
"Bar": 23,
"Parent": {
"$id": "10",
"Foo": 200
}
},
{
"$id": "6",
"Bar": 24,
"Parent": {
"$id": "11",
"Foo": 200
}
},
{
"$id": "7",
"Bar": 25,
"Parent": {
"$id": "12",
"Foo": 200
}
}
]
}
当然,在这种情况下,影响是很小的。但我的真实场景要大得多。