9

In my design 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'm using the Entity Framework to load and store this object to a database and I'm using Json.NET to serialize this object into JSON for further processing.

The problem I stumbled on is that the $type property is containing the typename of the EF proxy instead of the "real" typename. So instead of:

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

which is meaningless to other clients, I would like to get:

$type: "MyNamespace.CsvSource"

in my JSON.

What's the best way to achieve this?

4
  • 2
    Is disabling the use/creation of proxy objects an option for this code path? Read-only / eager-load use of EF doesn't seem to need it AFAICT? Commented Jun 6, 2014 at 12:43
  • 1
    Avoiding proxy generation (or disabling it by setting ProxyCreationEnabled to false) might be one strategy that applies in certain cases. However, there will be other cases where this is not applicable and my question remains open. Commented Jun 6, 2014 at 13:26
  • 1
    possible duplicate of Serialization of Entity Framework objects with One to Many Relationship Commented Jun 7, 2014 at 0:29
  • 1
    For people late to the show, the accepted answer is pretty lame; check out this one instead: stackoverflow.com/a/36621185/398630 Commented Oct 29, 2018 at 4:41

2 Answers 2

13

Another way which doesn't require you to make changes to your EF configuration is to use a custom SerializationBinder, e.g.:

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

Usage:

string json = JsonConvert.SerializeObject(entityFrameworkObject, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, Binder = new EntityFrameworkSerializationBinder() });
Sign up to request clarification or add additional context in comments.

3 Comments

Although functional, I'd suggest that anyone trying this take some performance measurements with this approach. I found it to be extremely slow.
@NateJackson Testing here shows the performance difference with and without the binder is negligible. I suspect the issue lies with EF. Is lazy loading enabled on your data context? If it is, the serialization process may be triggering round trips to the database which in turn will cause extremely slow performance. Try disabling lazy loading and use Include() to fetch related data before serializing.
This should be the correct answer! -- Turning off useful EF features is silly when we can just correct the undesired behavior.
3

You can do two things:

  • disabling tracking proxies, by setting ProxyCreationEnabled to false. You can find this property in your context's Configuration property. If you use a context for a single GetXxx method, you can do it without interfering other context instanced.

  • using the AsNoTracking() extension method when you recover your entity, like this:

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

This indicates that you don't want a tracking proxy for your entity, so you'll get the entity class. This has no interference with the afore mentioned configuration.

5 Comments

I guess you right. Although I could envision Json.NET to simply take the base class instead of the proxy when serializing.
Does anybody know a reference to a good documentation about side-effects of disabling proxy generation?
Here you have a great explanation: stackoverflow.com/questions/7111109/…
I had the same problem but it behaves wierdly.. xml serialization alone fails complaining the dynamic proxy stuffs but the json serialization works fine.. any thoughts
Please, open a new question, and explain it a little better. The behaviors and configuration of XML and JSON serializer are different, so it can be a different problem. If you do so, let me know, and I'll try to help you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.