How to prevent Json.NET from using proxy server type name Entity Framework?

In my project, I have a class that has a property whose type can be inherited from:

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

I use the Entity Framework to load and store this object in the database, and I use Json.NET to serialize this object to JSON for further processing.

The problem I came across is that the $type property contains the name of the EF proxy type instead of the "real" typename. Therefore, instead of:

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

which does not make sense to other clients, I would like to receive:

 $type: "MyNamespace.CsvSource" 

in my JSON.

What is the best way to achieve this?

+6
source share
2 answers

You can do two things:

  • disable proxy tracking by setting ProxyCreationEnabled to false. This property can be found in your Configuration context. If you use a context for one GetXxx method, you can do this without interfering with another context.

  • using the AsNoTracking() extension method when restoring your object, for example:

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

This means that you do not want a tracking proxy for your entity, so you will get an entity class. This does not interfere with the above configuration.

+4
source

Another way that does not require changes to the EF configuration is to use a special SerializationBinder, for example:

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

Using:

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

Source: https://habr.com/ru/post/970451/


All Articles