J'ai une classe DTO que je sérialise
Json.Serialize(MyClass)
Comment puis-je exclure une propriété publique?
(Cela doit être public, car je l'utilise dans mon code ailleurs)
Si vous utilisez System.Web.Script.Serialization
dans le framework .NET , vous pouvez définir un attribut ScriptIgnore
. sur les membres qui ne devraient pas être sérialisés. Voir l'exemple pris de ici :
Considérons le cas suivant (simplifié):
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. 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.
Si vous utilisez Json.Net , l'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 les attributs DataContract et DataMember pour sérialiser/désérialiser sélectivement les propriétés/champs.
[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; }
}
Reportez-vous à http://james.newtonking.com/archive/2009/10/23/efficient-json-with-json-net-reducing-serialized-json-size pour plus de détails.
Vous pouvez utiliser [ScriptIgnore]
:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
[ScriptIgnore]
public bool IsComplete
{
get { return Id > 0 && !string.IsNullOrEmpty(Name); }
}
}
Référence ici
Dans ce cas, l'identifiant puis le nom ne seront sérialisés
Si vous ne souhaitez pas décorer le code avec les attributs comme je le suis, surtout si vous ne pouvez pas dire au moment de la compilation ce qui va arriver, voici ma solution.
Utiliser le 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
}
}