Reputation: 10254
I'm using Newtonsoft JSON to serialize a graph of objects which are defined in a satellite assembly. I have a circular reference which is causing the recursion limit in JSON to be exceeded and adding extra bloat to an already data heavy POST.
The documented way would be to add a JsonIgnore
attribute to the property on my data object, but that would require a Newtonsoft.Json reference in my domain project. Is there any other way of excluding a property from serialization?
Upvotes: 2
Views: 331
Reputation: 10851
Alternative 1
You should be able to use [DataContract]
together with [DataMember]
.
[DataContract]
public class MyDomainModel
{
[DataMember]
public string PublicString { get; set; }
public string HiddenString { get; set; }
public MyDomainModel InfiniteReference { get; set; }
}
It requires a reference to System.Runtime.Serialization
.
Example:
[HttpGet]
public MyDomainModel GetModels()
{
var model = new MyDomainModel
{
HiddenString = "Hidden",
PublicString = "Public",
};
model.InfiniteReference = model;
return model;
}
Output:
{
"publicString": "Public"
}
Alternative 2
I have a circular reference [...]
You could use ReferenceLoopHandling
, which simply cuts the circular reference. But this might not be want you want, when you mentioned other extra bloat.
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
Upvotes: 3
Reputation: 4330
You can apply the [IgnoreDataMember]
attribute on the model properties, which references System.Runtime.Serialization
. All other properties will be serialized by default.
e.g.
public class MyViewModel
{
public string SerializedProperty { get; set; }
[IgnoreDataMember]
public string IgnoredProperty { get; set; }
}
Upvotes: 0
Reputation: 15578
Had a similar issue. I solved it in an entirely overwrought and overengineered fashion with a custom attribute and contract-resolver, when serializing, so I didn't need to reference any external libs (with the exception of System) in my model.
Declare your own attribute, such as
[AttributeUsage(AttributeTargets.Property)]
public sealed class IgnoreMeAttribute : Attribute
{
}
Decorate your model
[IgnoreMe]
public string IgnoreMePlease { get; set; }
Add a
public class ShouldSerializeContractResolver : DefaultContractResolver
{
public static readonly ShouldSerializeContractResolver Instance = new ShouldSerializeContractResolver();
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (property.AttributeProvider.GetAttributes(typeof (IgnoreMeAttribute), false).Any())
property.ShouldSerialize = instance => false;
return property;
}
}
and use it
var result = JsonConvert.SerializeObject(value, Formatting.None, new JsonSerializerSettings { ContractResolver = ShouldSerializeContractResolver.Instance });
Upvotes: 0