Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
463 views
in Technique[技术] by (71.8m points)

c# - JSON.NET Abstract / Derived Class Deserialization with WebAPI 2

I'm implementing a Web API 2 service that uses JSON.NET for serialization.

When I try to PUT ( deseralize ) updated json data, the abstract class is not present meaning it didn't know what to do with it so it did nothing. I also tried making the class NOT abstract and just inheriting from it and then each PUT deseralized to the base class rather than the derrived class missing the properties of the derrived class.

Example:

public class People
{
      // other attributes removed for demonstration simplicity

      public List<Person> People { get;set; }
}

public abstract class Person
{
      public string Id {get;set;}
      public string Name {get;set;}
}

public class Employee : Person 
{
      public string Badge {get;set;}
}

public class Customer : Person
{
     public string VendorCategory {get;set;}
}

with my web api configured to do typename handling:

public static void Register(HttpConfiguration config)
{
     config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = 
            TypeNameHandling.Objects;
}

then I PUT the JSON like:

{
     people: [{
          name: "Larry",
          id: "123",
          badge: "12345",
          $type: "API.Models.Employee, API"
     }]
}

to the web api method:

public HttpResponseMessage Put(string id, [FromBody]People value)
{
      people.Update(value); // MongoDB Repository method ( not important here )
      return Request.CreateResponse(HttpStatusCode.OK);
}

but the output when inspecting value is always:

People == { People: [] }

or if non-abstract:

People == { People: [{ Name: "Larry", Id: "123" }] }

missing the inherrited property. Anyone ran into this problem and come up with anything?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The $type function has to be the first attribute in the object.

In the above example I did:

 {
   people: [{
      name: "Larry",
      id: "123",
      badge: "12345",
      $type: "API.Models.Employee, API"
   }]
 }

after moving $type to the top like:

 {
   people: [{
      $type: "API.Models.Employee, API",
      name: "Larry",
      id: "123",
      badge: "12345"
   }]
 }

the serializer was able to deseralize the object to the correct cast. Gotta love that!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...