2014-06-06 17 views
6

在我的設計我有了其類型可以被繼承屬性的類:如何防止Json.NET使用Entity Framework代理類型名稱?

public class Feed 
{ 
    ... 
    [JsonProperty(TypeNameHandling = TypeNameHandling.Auto)] 
    public FeedSource Source { get; set; } 
    ... 
} 

public abstract class FeedSource { ... } 

public class CsvSource : FeedSource { ... } 

public class DbSource : FeedSource { ... } 

我使用實體框架加載這個對象存儲到數據庫中,我使用JSON。 NET將此對象序列化爲JSON以供進一步處理。

我偶然發現的問題是$type屬性包含EF代理的類型名稱而不是「真實」類型名稱。因此,而不是:

$type: "System.Data.Entity.DynamicProxies.CsvSource_0B3579D9BE67D7EE83EEBDDBFA269439AFC6E1122A59B4BB81EB1F0147C7EE12" 

這是毫無意義的其他客戶,我想獲得:

$type: "MyNamespace.CsvSource" 
在我的JSON

達到此目的的最佳方法是什麼?

+2

是禁止使用/創建代理對象這個代碼路徑的選項? EF的只讀/急切使用似乎並不需要它AFAICT? –

+0

避免代理生成(或通過將'ProxyCreationEnabled'設置爲false來禁用它)可能是在某些情況下適用的一種策略。但是,在其他情況下,這是不適用的,我的問題仍然存在。 – Dejan

+1

[Serialization of Entity Framework objects with One to Many Relationship](http://stackoverflow.com/questions/13077328/serialization-of-entity-framework-objects-with-one-to-many-relationship) –

回答

4

你可以做兩件事情:

  • 禁用跟蹤代理,通過設置ProxyCreationEnabled爲false。您可以在您的上下文的Configuration屬性中找到此屬性。如果您爲單個方法使用上下文,則可以在不干涉其他上下文實例的情況下執行此操作。

  • 使用AsNoTracking()擴展方法,當你恢復你的實體,像這樣:

    MyContext.MyTable.AsNoTracking(). // rest of the query here

這表明你不希望你的實體跟蹤代理,所以你獲得實體類。這與前述配置沒有干擾。

+0

我想你是對的。儘管我可以設想Json.NET在序列化時簡單地取代基類而不是代理。 – Dejan

+0

有沒有人知道有關禁用代理生成的副作用的良好文檔的參考? – Dejan

+0

在這裏你有一個很好的解釋:http://stackoverflow.com/questions/7111109/should-i-enable-or-disable-dynamic-proxies-with-entity-framework-4-1-and-mvc3 – JotaBe

4

不要求你更改您的EF配置另一種方法是使用自定義SerializationBinder,如:

class EntityFrameworkSerializationBinder : SerializationBinder 
{ 
    public override void BindToName(Type serializedType, out string assemblyName, out string typeName) 
    { 
     assemblyName = null; 

     if (serializedType.Namespace == "System.Data.Entity.DynamicProxies") 
      typeName = serializedType.BaseType.FullName; 
     else 
      typeName = serializedType.FullName; 
    } 

    public override Type BindToType(string assemblyName, string typeName) 
    { 
     throw new NotImplementedException(); 
    } 
} 

用法:

string json = JsonConvert.SerializeObject(entityFrameworkObject, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, Binder = new EntityFrameworkSerializationBinder() }); 
相關問題