J'ai une classe DTO que je sérialise.
Json.Serialize(MyClass)
Comment puis-je exclure un public propriété de celui-ci ?
(Il doit être public, car je l'utilise dans mon code quelque part ailleurs)
J'ai une classe DTO que je sérialise.
Json.Serialize(MyClass)
Comment puis-je exclure un public propriété de celui-ci ?
(Il doit être public, car je l'utilise dans mon code quelque part ailleurs)
Si vous utilisez Json.Net attribut [JsonIgnore]
ignorera simplement le champ/la propriété lors de la sérialisation ou de la désérialisation.
public class Car
{
// included in JSON
public string Model { get; set; }
public DateTime Year { get; set; }
public List<string> Features { get; set; }
// ignored
[JsonIgnore]
public DateTime LastModified { get; set; }
}
Vous pouvez également utiliser l'attribut DataContract et DataMember pour sérialiser/désérialiser les propriétés/champs de manière sélective.
[DataContract]
public class Computer
{
// included in JSON
[DataMember]
public string Name { get; set; }
[DataMember]
public decimal SalePrice { get; set; }
// ignored
public string Manufacture { get; set; }
public int StockCount { get; set; }
public decimal WholeSalePrice { get; set; }
public DateTime NextShipmentDate { get; set; }
}
Consultez le site http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size pour plus de détails
Si j'étais le PO, je préférerais cette réponse à la solution choisie [ScriptIgnore]. Principalement en raison de la congruence entre une solution Json et un problème Json. Pourquoi impliquer System.Web.Extensions quand la bibliothèque que vous utilisez fournit une solution ? La meilleure solution, selon moi, est l'attribut [IgnoreDataMember], car System.Runtime.Serialization devrait être compatible avec tous les sérialiseurs si vous souhaitez remplacer Json.
NewtonSoft vient de m'aider pleinement. Il a fait en sorte que mon json soit propre sans que des propriétés désordonnées soient incluses dans mes modèles qui sont juste pour le backend.
Si vous utilisez System.Web.Script.Serialization
dans le cadre de .NET vous pouvez mettre un ScriptIgnore
sur les membres qui ne doivent pas être sérialisés. Voir l'exemple tiré de aquí :
Considérons le cas (simplifié) suivant :
public class User { public int Id { get; set; } public string Name { get; set; } [ScriptIgnore] public bool IsComplete { get { return Id > 0 && !string.IsNullOrEmpty(Name); } } }
Dans ce cas, seules les propriétés Id et Name seront sérialisées, et l'objet JSON résultant ressemblera à ceci :
{ Id: 3, Name: 'Test User' }
PS. N'oubliez pas d'ajouter une référence à " System.Web.Extensions
"pour que cela fonctionne
Désolé, j'ai décidé d'écrire une autre réponse puisqu'aucune des autres réponses n'est assez copiable.
Si vous ne voulez pas décorer les propriétés avec certains attributs, ou si vous n'avez pas accès à la classe, ou si vous voulez décider de ce qu'il faut sérialiser pendant l'exécution, etc. etc. voici comment vous faites dans Newtonsoft.Json
//short helper class to ignore some properties from serialization
public class IgnorePropertiesResolver : DefaultContractResolver
{
private readonly HashSet<string> ignoreProps;
public IgnorePropertiesResolver(IEnumerable<string> propNamesToIgnore)
{
this.ignoreProps = new HashSet<string>(propNamesToIgnore);
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (this.ignoreProps.Contains(property.PropertyName))
{
property.ShouldSerialize = _ => false;
}
return property;
}
}
Utilisation
JsonConvert.SerializeObject(YourObject, new JsonSerializerSettings()
{ ContractResolver = new IgnorePropertiesResolver(new[] { "Prop1", "Prop2" }) });
Note : assurez-vous que vous mettez en cache le ContractResolver
si vous décidez d'utiliser cette réponse, sinon les performances peuvent en souffrir.
J'ai publié le code ici au cas où quelqu'un voudrait ajouter quelque chose.
L'URL dans votre réponse est cassé. Est-ce que [ScriptIgnore]
ce qui devrait être utilisé sur la propriété si votre contrôleur utilise la base MVC Controller return Json(...
?
Si vous n'êtes pas aussi enthousiaste que moi à l'idée de devoir décorer le code avec des attributs, surtout lorsque vous ne pouvez pas savoir au moment de la compilation ce qui va se passer, voici ma solution.
Utilisation du sérialiseur Javascript
public static class JsonSerializerExtensions
{
public static string ToJsonString(this object target,bool ignoreNulls = true)
{
var javaScriptSerializer = new JavaScriptSerializer();
if(ignoreNulls)
{
javaScriptSerializer.RegisterConverters(new[] { new PropertyExclusionConverter(target.GetType(), true) });
}
return javaScriptSerializer.Serialize(target);
}
public static string ToJsonString(this object target, Dictionary<Type, List<string>> ignore, bool ignoreNulls = true)
{
var javaScriptSerializer = new JavaScriptSerializer();
foreach (var key in ignore.Keys)
{
javaScriptSerializer.RegisterConverters(new[] { new PropertyExclusionConverter(key, ignore[key], ignoreNulls) });
}
return javaScriptSerializer.Serialize(target);
}
}
public class PropertyExclusionConverter : JavaScriptConverter
{
private readonly List<string> propertiesToIgnore;
private readonly Type type;
private readonly bool ignoreNulls;
public PropertyExclusionConverter(Type type, List<string> propertiesToIgnore, bool ignoreNulls)
{
this.ignoreNulls = ignoreNulls;
this.type = type;
this.propertiesToIgnore = propertiesToIgnore ?? new List<string>();
}
public PropertyExclusionConverter(Type type, bool ignoreNulls)
: this(type, null, ignoreNulls){}
public override IEnumerable<Type> SupportedTypes
{
get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { this.type })); }
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
var result = new Dictionary<string, object>();
if (obj == null)
{
return result;
}
var properties = obj.GetType().GetProperties();
foreach (var propertyInfo in properties)
{
if (!this.propertiesToIgnore.Contains(propertyInfo.Name))
{
if(this.ignoreNulls && propertyInfo.GetValue(obj, null) == null)
{
continue;
}
result.Add(propertyInfo.Name, propertyInfo.GetValue(obj, null));
}
}
return result;
}
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new NotImplementedException(); //Converter is currently only used for ignoring properties on serialization
}
}
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.
7 votes
Quel cadre de sérialisation utilisez-vous ?
42 votes
IgnoreDataMember
ScriptIgnore
JsonIgnore
en fonction du sérialiseur que vous utilisez3 votes
Il convient également de noter l'attribut [NonSerialized], qui n'est applicable qu'aux champs (et non aux propriétés), mais qui a le même effet que JsonIgnore.
0 votes
Le commentaire de Trynko est très utile.... si vous utilisez IgnoreDataMember sur un champ, il n'y aura pas d'erreur, mais il ne sera pas appliqué.
1 votes
Faites attention à vos espaces de noms. L'attribut [JsonIgnore] existe dans les espaces de noms Newtonsoft.Json et System.Text.Json.Serialization. Il est facile d'utiliser Newtonsoft.Json.JsonIgnore sur le modèle mais ensuite System.Text.Json.Serialization.JsonSerializer.Serialize pour sérialiser votre modèle (ou vice versa). L'attribut JsonIgnore est alors ignoré :)