[英]Self referencing loop detected where there is none
我有一個由TransformationPlanModel
的數據模型,該模型又包含IEnumerable<TransformationModel>
。 TransformationPlanModel
是根數據傳輸對象。 TransformationModel
是其他轉換模型的抽象基類。
摘錄了TransformationPlanModel
代碼:
public class TransformationPlanModel
{
// snip
public IEnumerable<TransformationModel> Transformations { get; set; }
}
剪下的TransformationModel
代碼:
public abstract class TransformationModel
{
//snip
public string Key { get; set; }
}
具體的轉換模型之一是RemoveRowsTransformationModel
:
public class RemoveRowsTransformationModel : TransformationModel
{
public const string KeyConst = "removeRows";
public int TopRowsCount { get; set; }
public int BottomRowsCount { get; set; }
public RemoveRowsTransformationModel()
{
Key = KeyConst;
}
//snip
}
我已經編寫了一個自定義JsonConverter
,它可以轉換TransformationModel
繼承樹。 JsonWrite
方法的實現是:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JObject.FromObject(value, serializer).WriteTo(writer);
}
自定義轉換器在ASP.NET Core API應用程序中使用,並添加到Startup.ConfigureServices
方法中的服務中,如下所示:
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.Converters.Add(new TransformationConverter());
});
當從API端點作為響應返回TransformationPlanModel
並進行序列化時,將引發Newtonsoft.Json.JsonSerializationException
,其中包含以下消息:“檢測到類型為'(...)。RemoveRowsTransformationModel'的自引用循環”。 是什么導致此異常? 我看不到自我引用循環在哪里。 我不知道這是否重要,但是我正在使用.NET Core 2.0 Preview 1。
有趣的是,當過載JObject.FromObject
而不串行參數在使用WriteJson
方法,它工作正常:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JObject.FromObject(value).WriteTo(writer);
}
但是,這會重置序列化設置,例如駱駝箱屬性命名。 我也嘗試過忽略Json.Net設置中的循環引用,但是那時沒有序列化任何轉換。
該錯誤所指的“自引用循環”是您的轉換器調用自身。 串行器的設置可使其直接使用您的轉換器。 您的轉換器調用JObject.FromObject()
,並傳入序列化程序。 JObject.FromObject
使用序列化程序來嘗試從您的模型創建JObject
。 然后,串行器再次調用您的轉換器,依此類推。 Json.Net檢測到此遞歸循環並引發異常。
一種可能的解決方案是使用新的序列化程序實例,從原始序列化程序復制所有設置,但轉換器除外:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JsonSerializer ser2 = new JsonSerializer();
foreach (PropertyInfo prop in typeof(JsonSerializer).GetProperties()
.Where(p => p.Name != nameof(JsonSerializer.Converters)))
{
prop.SetValue(ser2, prop.GetValue(serializer));
}
JObject.FromObject(value, ser2).WriteTo(writer);
}
但是,由於您的WriteJson
方法似乎不執行任何操作,而只是加載對象並立即將其寫出而沒有任何更改,因此,更好的解決方案是簡單地重寫CanWrite
以返回false。 然后, WriteJson
不會調用WriteJson
,而將使用默認的序列化,無論如何,這似乎是您想要發生的事情。
public override bool CanWrite
{
get { return false; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.