J'utilise une API Web MVC 4 et des formulaires Web asp.net 4.0 pour créer une API de repos. Cela fonctionne très bien:
[HttpGet]
public HttpResponseMessage Me(string hash)
{
HttpResponseMessage httpResponseMessage;
List<Something> somethings = ...
httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK,
new { result = true, somethings = somethings });
return httpResponseMessage;
}
Maintenant, je dois empêcher certaines propriétés d'être sérialisées. Je sais que je peux utiliser du LINQ sur la liste et obtenir uniquement les propriétés dont j'ai besoin, et généralement c'est une bonne approche, mais dans le scénario actuel, lesomething
objet est trop complexe, et j'ai besoin d'un ensemble différent de propriétés dans différentes méthodes, donc c'est plus facile à marquer, lors de l'exécution, chaque propriété à ignorer.
Y-a-t-il un moyen de faire ça?
c#
asp.net
asp.net-mvc
asp.net-web-api
user1330271
la source
la source
Réponses:
L'API Web ASP.NET utilise
Json.Net
comme formateur par défaut, donc si votre application utilise uniquement JSON comme format de données, vous pouvez utiliser[JsonIgnore]
pour ignorer la propriété pour la sérialisation:Mais cette méthode ne prend pas en charge le format XML. Ainsi, au cas où votre application doit davantage prendre en charge le format XML (ou uniquement prendre en charge XML), au lieu d'utiliser
Json.Net
, vous devez utiliser[DataContract]
ce qui prend en charge à la fois JSON et XML:Pour plus de compréhension, vous pouvez lire l' article officiel .
la source
Selon la page de documentation de l'API Web Sérialisation JSON et XML dans l'API Web ASP.NET pour empêcher explicitement la sérialisation sur une propriété, vous pouvez soit utiliser
[JsonIgnore]
pour le sérialiseur Json, soit[IgnoreDataMember]
pour le sérialiseur XML par défaut.Cependant, lors des tests, j'ai remarqué que cela
[IgnoreDataMember]
empêche la sérialisation pour les requêtes XML et Json, donc je recommanderais de l'utiliser plutôt que de décorer une propriété avec plusieurs attributs.la source
[IgnoreDataMember]
ne semble pas fonctionner avec les objets proxy EF 6 chargés paresseusement (propriétés virtuelles).[DataContract]
et[DataMember]
faire, cependant.Au lieu de laisser tout être sérialisé par défaut, vous pouvez adopter l'approche «opt-in». Dans ce scénario, seules les propriétés que vous spécifiez sont autorisées à être sérialisées. Pour ce faire, utilisez
DataContractAttribute
etDataMemberAttribute
, qui se trouve dans l' espace de noms System.Runtime.Serialization .Le
DataContactAttribute
est appliqué à la classe et leDataMemberAttribute
est appliqué à chaque membre que vous souhaitez sérialiser:Oserais-je dire que c'est une meilleure approche, car elle vous oblige à prendre des décisions explicites sur ce qui le fera ou ne le fera pas grâce à la sérialisation. Cela permet également à vos classes de modèles de vivre par elles-mêmes dans un projet, sans prendre de dépendance sur JSON.net simplement parce qu'ailleurs, vous les sérialisez avec JSON.net.
la source
Cela a fonctionné pour moi: créez un résolveur de contrat personnalisé qui a une propriété publique appelée AllowList de type tableau de chaînes. Dans votre action, modifiez cette propriété en fonction de ce que l'action doit renvoyer.
1. créez un résolveur de contrat personnalisé:
2. Utilisez le résolveur de contrat personnalisé en action
Cette approche m'a permis d'autoriser / interdire des demandes spécifiques au lieu de modifier la définition de classe. Et si vous n'avez pas besoin de la sérialisation XML, n'oubliez pas de la désactiver dans votre
App_Start\WebApiConfig.cs
ou votre API renverra des propriétés bloquées si le client demande xml au lieu de json.la source
Je vais vous montrer 2 façons d'accomplir ce que vous voulez:
Première façon: Décorez votre champ avec l'attribut JsonProperty afin d'ignorer la sérialisation de ce champ s'il est nul.
Deuxième méthode: si vous négociez avec certains scénarios complexes, vous pouvez utiliser la convention Web Api ("ShouldSerialize") afin de sauter la sérialisation de ce champ en fonction d'une logique spécifique.
WebApi utilise JSON.Net et utilise la réflexion pour la sérialisation, donc quand il a détecté (par exemple) la méthode ShouldSerializeFieldX (), le champ avec le nom FieldX ne sera pas sérialisé.
la source
Je suis en retard au jeu, mais un objet anonyme ferait l'affaire:
la source
Essayez d'utiliser la
IgnoreDataMember
propriétéla source
Presque identique à la réponse de greatbear302, mais je crée ContractResolver par requête.
1) Créer un ContractResolver personnalisé
2) Utilisez le résolveur de contrat personnalisé en action
Éditer:
Cela n'a pas fonctionné comme prévu (isoler le résolveur par requête). J'utiliserai des objets anonymes.
la source
Vous pourrez peut-être utiliser AutoMapper et utiliser le
.Ignore()
mappage, puis envoyer l'objet mappéla source
Fonctionne très bien en ajoutant simplement le: [IgnoreDataMember]
En plus du type de propriété, comme:
Cela fonctionne avec ApiController. Le code:
la source
Pour une raison quelconque,
[IgnoreDataMember]
cela ne fonctionne pas toujours pour moi, et je reçois parfoisStackOverflowException
(ou similaire). Donc, à la place (ou en plus), j'ai commencé à utiliser un modèle ressemblant à quelque chose comme ça lorsque je suisPOST
entré dansObjects
mon API:Donc, fondamentalement, je passe dans un
JObject
et le convertis après qu'il a été reçu en évitant les problèmes causés par le sérialiseur intégré qui provoquent parfois une boucle infinie lors de l'analyse des objets.Si quelqu'un connaît une raison pour laquelle c'est une mauvaise idée, faites-le moi savoir.
Il peut être intéressant de noter que c'est le code suivant pour une propriété de classe EntityFramework qui provoque le problème (si deux classes se réfèrent l'une à l'autre):
la source