问题
I have an API that returns a big list of car features.... all are either bool or ints... and basically I only want to display the ones that return true values or >0 for the ints.
I am using JSON.net so that I san use the ShouldSerialize() property to determine if I should serialize the property based upon its value and my code looks like this:
public class Features
{
public bool ABS { get; set; }
public bool ShouldSerializeABS()
{
// don't serialize the ABS property if ABS is false
return (ABS != false);
}
public bool Immobiliser { get; set; }
public bool ShouldSerializeImmobiliser ()
{
// don't serialize the Immobiliser property if Immobiliser is false
return (Immobiliser != false);
}
public int BHP { get; set; }
public bool ShouldSerializeBHP ()
{
// don't serialize the BHP property if BHP is false
return (BHP != 0);
}
//..... etc
}
This works great and gives me the results I am after, however I was just wondering if there is a way to re-factor this so that my class does not become cluttered with all the ShouldSerialize() properties?
I have been looking into CopyConditional
properties with IContractResolver
on http://james.newtonking.com/projects/json/help/index.html?topic=html/ConditionalProperties.htm and looks like it might be possible to use IContractResolver
for such a purpose, but I still seem to end up with lots of code that does not seem to re-factor out
public class ShouldSerializeContractResolver : DefaultContractResolver
{
public new static readonly ShouldSerializeContractResolver Instance = new ShouldSerializeContractResolver();
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (property.DeclaringType == typeof(Features) && property.PropertyName == "ABS")
{
property.ShouldSerialize =
instance =>
{
Features e = (Features)instance;
return e.ABS != false;
};
}
if (property.DeclaringType == typeof(Features) && property.PropertyName == "Immobiliser")
{
property.ShouldSerialize =
instance =>
{
Features e = (Features)instance;
return e.Immobiliser != false;
};
}
return property;
}
}
and this method using the ShouldSerializeContractResolver does not seem to remove the property from the class if it is false... any help is greatly appreciated
回答1:
It sounds like what you are trying to accomplish by writing all these ShouldSerialize() methods can be accomplished by just changing the DefaultValueHandling
setting on the serializer to Ignore. This will cause any values that are equal to their default values (false for bool, 0 for int) not to be serialized.
JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
jsonSettings.DefaultValueHandling = DefaultValueHandling.Ignore;
string json = JsonConvert.SerializeObject(yourObject, jsonSettings);
If you're using Web API, then you can access the settings of the Json.NET serializer via the Register
method of the WebApiConfig
class (in the App_Start folder).
JsonSerializerSettings settings = config.Formatters.JsonFormatter.SerializerSettings;
settings.DefaultValueHandling = DefaultValueHandling.Ignore;
来源:https://stackoverflow.com/questions/16317026/refactor-of-shouldserialize-in-class-can-i-use-icontractresolver