J'implémente un service Web API 2 qui utilise JSON.NET pour la sérialisation.
Lorsque j'essaie de PUT (désserrer) les données JSON mises à jour, la classe abstraite n'est pas présente, ce qui signifie qu'elle ne savait pas quoi en faire; elle n'a donc rien fait. J'ai également essayé de rendre la classe NON abstraite et d'en hériter, puis chaque PUT est déseralisé dans la classe de base plutôt que de laisser à la classe dérivée les propriétés de la classe dérivée.
Exemple:
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;}
}
avec mon api web configuré pour gérer les noms de fichiers:
public static void Register(HttpConfiguration config)
{
config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling =
TypeNameHandling.Objects;
}
alors je mets le JSON comme:
{
people: [{
name: "Larry",
id: "123",
badge: "12345",
$type: "API.Models.Employee, API"
}]
}
à la méthode web api:
public HttpResponseMessage Put(string id, [FromBody]People value)
{
people.Update(value); // MongoDB Repository method ( not important here )
return Request.CreateResponse(HttpStatusCode.OK);
}
mais la sortie lors de l'inspection value
est toujours:
People == { People: [] }
ou si non abstrait:
People == { People: [{ Name: "Larry", Id: "123" }] }
manque la propriété héritée. Quelqu'un at-il rencontré ce problème et a trouvé quelque chose?
La fonction $type
doit être le premier attribut de l'objet.
Dans l'exemple ci-dessus, j'ai:
{
people: [{
name: "Larry",
id: "123",
badge: "12345",
$type: "API.Models.Employee, API"
}]
}
après avoir déplacé $type
vers le haut comme:
{
people: [{
$type: "API.Models.Employee, API",
name: "Larry",
id: "123",
badge: "12345"
}]
}
le sérialiseur était capable de dessaler l'objet au bon casting. Je dois aimer ça!
JsonSubTypes library permet de spécifier la sous-classe de la classe à utiliser pour la désérialisation en attributs via, exactement comme le fait la bibliothèque Jackson en Java. Pour être plus précis, vous pouvez:
Je sais que ce message est ancien et que la réponse a été marquée, mais je pensais que ma solution pourrait être utile ....
Essayez d'ajouter l'attribut JsonProperty aux propriétés de votre classe abstraite.
using JTC.Framework.Json;
...
public class People
{
// other attributes removed for demonstration simplicity
public List<Person> People { get;set; }
}
public abstract class Person
{
[JsonProperty()]
public string Id {get;set;}
[JsonProperty()]
public string Name {get;set;}
}
public class Employee : Person
{
public string Badge {get;set;}
}
public class Customer : Person
{
public string VendorCategory {get;set;}
}
J'ai essayé votre scénario maintenant et cela fonctionne bien. Mais j'ai remarqué qu'il vous manque un ,
(virgule) après la propriété id
dans votre entrée json.
Je l'ai compris en utilisant le contrôle de validité ModelState suivant dans mon action, qui a ensuite montré l'erreur dans la charge utile de ma demande. Cela pourrait vous être utile aussi:
if (!ModelState.IsValid)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, this.ModelState);
}