2014-06-06 14 views
6

W moim projekcie mam klasę, która ma właściwość, którego typ może być dziedziczone od:Jak uniemożliwić Json.NET korzystanie z nazwy typu proxy serwera 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 { ... } 

Używam Entity Framework do ładowania i przechowywania tego obiektu do bazy danych i używam json. NET do serializacji tego obiektu do JSON w celu dalszego przetwarzania.

Problem, na który natrafiłem, polega na tym, że właściwość $type zawiera nazwę pliku proxy pośredniczącego EF zamiast "rzeczywistego" typu. Więc zamiast:

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

co jest bez znaczenia dla innych klientów, chciałbym dostać:

$type: "MyNamespace.CsvSource" 

w moim JSON.

Jaki jest najlepszy sposób, aby to osiągnąć?

+2

jest wyłączenie użycia/tworzenie obiektów proxy jest opcją dla tej ścieżki kodu? Wykorzystanie EF w trybie tylko do odczytu/przydaje się do ładowania nie wydaje się, aby było to potrzebne AFAICT? –

+0

Unikanie generowania proxy (lub wyłączanie go przez ustawienie "ProxyCreationEnabled" na false) może być jedną z strategii, która ma zastosowanie w niektórych przypadkach. Będą jednak inne przypadki, w których nie ma to zastosowania, a moje pytanie pozostaje otwarte. – Dejan

+1

możliwy duplikat obiektów [Serializacja obiektów z jednym do wielu relacji] (http://stackoverflow.com/questions/13077328/serialization-of-entimes- frame-objects-with-one-to-many-relationship) –

Odpowiedz

4

Można zrobić dwie rzeczy:

  • wyłączenie śledzenia proxy, poprzez ustawienie ProxyCreationEnabled false. Możesz znaleźć tę właściwość we właściwościach kontekstu: Configuration. Jeśli używasz kontekstu dla pojedynczej metody GetXxx, możesz to zrobić bez zakłócania innych kontekstów.

  • stosując metodę AsNoTracking() wewnętrzny Jeśli odzyskać podmiot, na przykład:

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

Oznacza to, że nie chcesz proxy śledzenia dla swojej jednostki, więc będziesz zdobądź klasę encji. Nie ma to wpływu na powyższą konfigurację.

+0

Myślę, że masz rację. Chociaż mogłem sobie wyobrazić Json.NET po prostu wziąć klasę podstawową zamiast proxy podczas serializacji. – Dejan

+0

Czy ktoś zna odniesienie do dobrej dokumentacji na temat skutków ubocznych wyłączenia generowania proxy? – Dejan

+0

Tutaj masz wielkie wyjaśnienie: http://stackoverflow.com/questions/7111109/może--dodatkowe-lub-dodalne-dynamiczne-przypomnienia-z-strona-ramka-4-1-i -mvc3 – JotaBe

4

Innym sposobem, który nie wymaga, aby dokonać zmian w konfiguracji EF jest użycie niestandardowego SerializationBinder, np:

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(); 
    } 
} 

Zastosowanie:

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