如果你不关心你的JSON中有一些额外的簿记信息,然后在JsonSerializerSettings
到All
(或Objects
)设置PreserveReferenceHandling
选项,@Athari建议。这是使其工作的最简单方法。如果你这样做,你的JSON应该是这样的:
{
"$id": "1",
"Id": 123,
"OtherStuff": "other stuff A",
"MyChild": {
"$id": "2",
"Id": 456,
"OtherStuff": "other stuff B",
"MyParent": {
"$ref": "1"
}
}
}
这就是说,有一种方法做你原来想要的东西,使用自定义JsonConverter
。你可以做的是制作一个转换器,它将接受任何具有Id属性的对象。然后,对于那些您希望将其仅序列化为ID的地方,可以使用[JsonConverter]
属性修饰这些属性。自定义转换器将用于这些情况,但不会以其他方式使用。以下是转换器的外观:
class IdOnlyConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.IsClass;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteStartObject();
writer.WritePropertyName("Id");
writer.WriteValue(GetId(value));
writer.WriteEndObject();
}
private int GetId(object obj)
{
PropertyInfo prop = obj.GetType().GetProperty("Id", typeof(int));
if (prop != null && prop.CanRead)
{
return (int)prop.GetValue(obj, null);
}
return 0;
}
public override bool CanRead
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
要使用转换器,您需要按照您的说明设置类。请注意0如何用属性修饰来告诉Json.Net使用该属性的自定义转换器。
public class ObjA
{
public int Id { get; set; }
public string OtherStuff { get; set; }
public ObjB MyChild { get; set; }
}
public class ObjB
{
public int Id { get; set; }
public string OtherStuff { get; set; }
[JsonConverter(typeof(IdOnlyConverter))]
public ObjA MyParent { get; set; }
}
序列化时,您将需要的JsonSerializerSettings
的ReferenceLoopHandling
选项设置为Serialize
告诉Json.Net如果检测到参考回路不是抛出一个错误,并继续反正序列化(因为我们的转换器将处理它)。
全部放在一起,这里是一些示例代码演示了正在运行的转换器:
class Program
{
static void Main(string[] args)
{
ObjA a = new ObjA();
a.Id = 123;
a.OtherStuff = "other stuff A";
ObjB b = new ObjB();
b.Id = 456;
b.OtherStuff = "other stuff B";
b.MyParent = a;
a.MyChild = b;
JsonSerializerSettings settings = new JsonSerializerSettings
{
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize,
Formatting = Newtonsoft.Json.Formatting.Indented
};
string json = JsonConvert.SerializeObject(a, settings);
Console.WriteLine(json);
}
}
这里是上面的输出:
{
"Id": 123,
"OtherStuff": "other stuff A",
"MyChild": {
"Id": 456,
"OtherStuff": "other stuff B",
"MyParent": {
"Id": 123
}
}
}
哦,好的,是的,我创建了一个转换器,但不知道如何让他进入属性。这将工作正常。感谢你们两位。 – Raif
嗨,所以一切都很好,除了我得到这个错误{“Message”:“发生错误”, “ExceptionMessage”:“'ObjectContent'1'类型未能序列化内容类型的响应主体'application/json; charset = utf-8'。“, ”ExceptionType“:”System.InvalidOperationException“, ”StackTrace“:null, ”InnerException“:{ ”Message“:”发生错误。 , “ExceptionMessage”:“错误创建GuidEntityToIdJsonConverter”, “ExceptionType”:“Newtonsoft.Json.JsonException”, – Raif
哇抱歉缺乏在这个堆栈跟踪结束格式化 – Raif