2 votes

Désérialisation en classe dérivée dans ASP.NET Web API

Dans ma dernière question SO, j'ai demandé comment modifier les paramètres du sérialiseur pour Json.NET, que ASP.NET Web API utilise nativement pour la (dé)sérialisation. La réponse acceptée a parfaitement fonctionné, et j'ai ainsi pu incorporer des informations de type dans la chaîne JSON sérialisée.

Cependant, lorsque j'essaie de renvoyer cette chaîne JSON à une action Web API qui attend la classe parent du modèle, Web API désérialise toujours vers la classe parent, supprime toutes les données correspondant à la classe enfant et empêche le cast et la détection de la classe enfant.

class Entity { }
class Person : Entity { }

public Person Get() {
    return new Person();
}

public bool Post(Entity entity) {
    return entity is Person;
}

Un cas d'utilisation simple consisterait à faire quelque chose comme ceci en jQuery :

// obtenir un objet Person JSON sérialisé
$.ajax({
    url : 'api/person'      // PersonController
}).success(function (m) {

    // puis renvoyer directement cet objet Person via une requête HTTP POST
    $.ajax({
        url : 'api/person',
        type : 'POST',
        data : m
    }).success(function (m) {
        console.log(m);     // false
    });

})

Je m'attendais à ce qu'en modifiant les JsonSerializerSettings de Json.NET pour incorporer des informations de type, il serait capable de les lire et, au moins, d'essayer de forcer la désérialisation vers ce type, mais apparemment il ne le fait pas.

Comment devrais-je aborder un problème comme celui-ci?

1voto

Darrel Miller Points 56797

Web API ne fait vraiment aucune (dé)sérialisation "nativement". Il se trouve qu'il a quelques MediaTypeFormatters inclus dans la collection config.Formatters par défaut. N'hésitez pas à les supprimer et à créer votre propre MediaTypeFormatter qui gère la sérialisation de la manière dont vous souhaitez qu'elle soit faite.

Les MediaTypeFormatters ne sont vraiment pas si difficiles à créer.

1voto

Maggie Ying Points 3804

En fait, le 2ème appel POST envoie des données au format application/x-www-form-urlencoded et c'est pourquoi les informations de type ne sont pas prises en compte par JsonMediaTypeFormatter. Essayez de définir le contentType sur "application/json".

De plus, les données dans le corps de la 2ème requête POST semblent être encodées et doivent être décodées avant d'être renvoyées au service.

J'ai réussi à faire fonctionner cela :

// obtenir une Personne JSON sérialisée
$.ajax({
    url: 'api/person'      // PersonController
}).success(function (m) {

    // puis renvoyer cette Personne via HTTP POST
    $.ajax({
        url: 'api/person',
        type: 'POST',
        contentType: "application/json",
        data: JSON.stringify(m),
    }).success(function (m) {
        alert(m);     // vrai !
    });

})

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X