Inheritance of EF TPH lost in Web Api JSON

I have successfully created a number of classes that use TPH EF inheritance , MyBaseClass, MySubClass1, MySubClass2, etc.

When querying using Linq, the context.MyBaseClasses.Where(...)objects returned by all correctly use the subclass specified by the Discriminator field in the database. (That way, I could make a list containing a combination of objects MySubClass1or MySubClass2.)

However, when I pass these objects to a WPF application, through a JSON Web Api call, the received objects have everything MyBaseClass, and not the correct subclass from which they started.

The property of the object that they return is of type public virtual List<MyBaseClass> MyThings, so I assume that it makes sense that they all end as this type, but I want to keep the correct subclass type for each object.

How do I achieve this? Do I need to force the EF Discriminator field to be sent along with all other data?

Edit

1.

On the client side, I am now trying to deserialize JSON (including data like $) in the same way (with no luck, the elements are still converted back to their base class)

HttpResponseMessage response = GetClient().GetAsync(url).Result;

if (response.IsSuccessStatusCode)
{
    string jsonMessage;
    using (Stream responseStream = response.Content.ReadAsStreamAsync().Result)
    {
        jsonMessage = new StreamReader(responseStream).ReadToEnd();
    }


    List<My.Domain.Models.MyBaseClass> thingsToReturn;

    //new method    
    thingsToReturn = JsonConvert.DeserializeObject<List<My.Domain.Models.MyBaseClass>>(jsonMessage);

    //previous method
    //thingsToReturn = response.Content.ReadAsAsync<List<My.Domain.Models.MyBaseClass>>().Result;

    return thingsToReturn;
}

2.

Following Anish re’s advice SerializerSettings.TypeNameHandling, I now have information about the type of the type in my JSON, but this is the type of the type System.Data.Entity.DynamicProxies.SubClass1_5E07A4CE2F037430DC7BFA00593...., is it ok for the client end to deserialize successfully back to SubClass1?

+4
source share
2 answers

, Anish, , .

, , - api, :

JsonFormatter Serializer TypeNameHandling TypeNameHandling.Auto. WebApiConfig.Register(), , , $type JSON, -, , $for.

WebApiConfig

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto;        

[Newtonsoft.Json.JsonProperty(ItemTypeNameHandling = Newtonsoft.Json.TypeNameHandling.Auto)]
public virtual List<MyBaseClass> Things { get; set; }

$type JSON, - EF, ProxyCreationEnabled Linq, MyBaseClass.

dbContext.Configuration.ProxyCreationEnabled = false;
List<MyBaseClass> things = dbContext.MyBaseClasses.Include("This").Include("That").ToList();

JsonMediaTypeFormatter SerializerSettings = { TypeNameHandling = TypeNameHandling.Auto } ReadAsAsync(), ( ) , .

HttpResponseMessage response = GetClient().GetAsync(url).Result;

if (response.IsSuccessStatusCode)
{
    //this formatter responds to the $type parameter passed in the JSON to allow us to correctly map object types
    //https://kirmir.wordpress.com/2014/05/16/polymorphic-serialization-using-newton-json-net-in-httpcontent/
    var formatter = new JsonMediaTypeFormatter
    {
        SerializerSettings = { TypeNameHandling = TypeNameHandling.Auto }
    };

    List<MyBaseClass> thingsToReturn;
    thingsToReturn = response.Content.ReadAsAsync<List<MyBaseClass>>(new List<MediaTypeFormatter> { formatter }).Result;
    return productTestsToReturn;
}
+1

.

Json.Net json.

HttpConfiguration:

config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.Auto;

config - HttpConfiguration, Asp.Net WebApi.

Json.Net json, . :

{
    "$type":"MyProjectContainingMyTypes.MySubClass1, MyProjectContainingMyTypes",
    "Name": "Tyrion Lannister",
    "DisplayName": "The Imp",
    "Traits": ["funny", "awesome", "clever"]
}

Json.Net , , deserialize WPF.

WPF:

var things = JsonConvert.DeserializeObject<List<MyBaseClass>>(jsonString);

things .

, WPF , MyBaseClass MySubClass1.

Edit

, . $ JSON, dunce, , WebApi jsonString? , . .ReadAsAsync > (). ; .

:

var jsonString = response.Content.ReadAsStringAsync().Result;

2

, . , JSON , JsonConvert.DeserializeObject . , ( 2), $ ( - EF)?

, - EF . WebApi.

- , . / . , , , .

EF.

WebApi , , EF .

:

1

ToList() :

var result = (from t in dbContext.Things select t).ToList();

var result = dbContext.Things.ToList();

, , :

var result = (from t in dbContext.Things select t).Skip(0).Take(10).ToList();

var result = dbContext.Things.Skip(0).Take(10).ToList();

, :

var result = dbContext
             .Things
             .Include(t => t.SomePropertyThatRepresentsSomeNestedObject) 
             .Skip(0)
             .Take(10)
             .ToList();

2

DbContext.

1, , , .

+3

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


All Articles