簡體   English   中英

ASP.NET API序列化具有循環依賴關系的實體

[英]ASP.NET API serialize entities with circular dependencies

我有Test實體和User實體。

測試:

public class Test
{
  public int Id {get; set;}
  public string Title {get; set;}
  ...
  public virtual IList<User> Users {get; set;}
}

用戶:

public class User
{
  public int Id {get; set;}
  public string Name {get; set;}
  ...
  public virtual IList<Test> Tests {get; set;}
}

在我的TestsApiController我可以執行以下操作:

public IQueryable<Test> GetTests()
{
    return db.Tests;
}

這將返回序列化異常,因為它嘗試對User對象,其Test對象,然后對它們的User對象進行循環序列化。

我目前的計划是建立一個TestDTO其中包含IList<int> UserIds ,而不是實際的對象。 然后我將不得不在序列化之前將所有Test對象轉換為TestDTO對象,這有點煩人。 然后,如果我想序列化具有循環依賴關系的其他實體,則必須為其創建更多的數據傳輸對象。

有沒有一種方法可以創建或配置一個序列化程序,以便在這種情況下將User (或任何其他)對象自動序列化為簡單的Id屬性?

編輯帶有例外:無論使用XML還是JSON我都會遇到相同的異常

<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace/>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'System.Data.Entity.DynamicProxies.Test_6585C5F85A384907958ABA03B661933EF718BDEDE1513392E060DE06E80DB552' with data contract name 'Test_6585C5F85A384907958ABA03B661933EF718BDEDE1513392E060DE06E80DB552:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
</ExceptionMessage>
<ExceptionType>
System.Runtime.Serialization.SerializationException
</ExceptionType>
<StackTrace>...</StackTrace>
</InnerException>
</Error>

構造json結果的一種非常簡單的方法是使用NewtonSoft json序列化程序中的JObject(通常是ASP.NET Web Api中的默認值)。 您正在尋找的東西看起來像

public JObject GetTests()
{

    NewtonSoft.Json.Linq.JObject jsonResult = NewtonSoft.Json.Linq.JObject.FromObject(new 
    {
        Tests = from test in db.tests
                select new 
                {
                    Id = test.Id,
                    Title = test.Title,
                    Users = from user in test.Users
                            select new
                            {
                                Id = user.Id
                            }
                }
    });

    return jsonResult;
}

這使您可以更好地控制json結果,因此您可以選擇要序列化的字段/屬性,並避免創建大量數據傳輸對象。 希望這可以幫助。

干杯

在您的Web API配置(App_Start / WebApiConfig.cs)中,添加以下代碼:

    public static class WebApiConfig
    {
      public static void Register(HttpConfiguration config)
      {
        // Prevent "Self referencing loop detected" error occurring for recursive objects
        var serializerSettings = new JsonSerializerSettings()
        {
            ReferenceLoopHandling = ReferenceLoopHandling.Ignore
        };
        config.Formatters.JsonFormatter.SerializerSettings = serializerSettings;
      }
    }

這告訴JSON.NET忽略引用父對象的嵌套對象

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM