How to Optionally Turn Off the JSONignore Attribute at Runtime

Can I optionally turn off the JsonIgnore attribute at runtime?

Yes, this can be done using a custom ContractResolver.

You didn't show any code, so I'll just make up an example. Let's say I have a class Foo as shown below. I want the Id and Name properties in the serialization output, but I'm definitely not interested in the AlternateName and Color. I've marked those with [JsonIgnore]. I want the description to appear, but sometimes this can get really long, so I've used a custom JsonConverter to limit its length. I also want to use a shorter property name for the description, so I've marked it with [JsonProperty("Desc")].

class Foo
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
public string AlternateName { get; set; }
[JsonProperty("Desc")]
[JsonConverter(typeof(StringTruncatingConverter))]
public string Description { get; set; }
[JsonIgnore]
public string Color { get; set; }
}

When I serialize an instance of the above...

Foo foo = new Foo
{
Id = 1,
Name = "Thing 1",
AlternateName = "The First Thing",
Description = "This is some lengthy text describing Thing 1 which you'll no doubt find very interesting and useful.",
Color = "Yellow"
};

string json = JsonConvert.SerializeObject(foo, Formatting.Indented);

...I get this output:

{
"Id": 1,
"Name": "Thing 1",
"Desc": "This is some lengthy text describing Thing 1 "
}

Now, let's say that I sometimes want to get the full JSON output, ignoring my customizations. I can use a custom ContractResolver to programmatically "unapply" the attributes from the class. Here's the code for the resolver:

class IgnoreJsonAttributesResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
foreach (var prop in props)
{
prop.Ignored = false; // Ignore [JsonIgnore]
prop.Converter = null; // Ignore [JsonConverter]
prop.PropertyName = prop.UnderlyingName; // restore original property name
}
return props;
}
}

To use the resolver, I add it to the JsonSerializerSettings and pass the settings to the serializer like this:

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new IgnoreJsonAttributesResolver();
settings.Formatting = Formatting.Indented;

string json = JsonConvert.SerializeObject(foo, settings);

The output now includes the ignored properties, and the description is no longer truncated:

{
"Id": 1,
"Name": "Thing 1",
"AlternateName": "The First Thing",
"Description": "This is some lengthy text describing Thing 1 which you'll no doubt find very interesting and useful.",
"Color": "Yellow"
}

Full demo here: https://dotnetfiddle.net/WZpeWt

Ignore [JsonIgnore] Attribute on Serialization / Deserialization

You were on the right track, you only missed the property.Ignored serialization option.

Change your contract to the following

public class JsonIgnoreAttributeIgnorerContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
property.Ignored = false; // Here is the magic
return property;
}
}

NewtonSoft add JSONIGNORE at runTime

No need to do the complicated stuff explained in the other answer.

NewtonSoft JSON has a built-in feature for that:

public bool ShouldSerializeINSERT_YOUR_PROPERTY_NAME_HERE()
{
if(someCondition){
return true;
}else{
return false;
}
}

It is called "conditional property serialization" and the documentation can be found here.

Warning: first of all, it is important to get rid of [JsonIgnore] above your {get;set;} property. Otherwise it will overwrite the ShouldSerializeXYZ behavior.

Newtonsoft ignore attributes?

I ended up making all properties I needed to only add attributes to virtual, and overriding them alone in another class, with the relevant newtonsoft attributes.

This allows me to have different serialisation behavior when de-serialising from CouchDB and serialising for a GET, without too much dupe. It is fine, and a bonus, that the two are coupled; any changes in the base i would want anyway.

It would still be nice to know if my original question is possible?

JsonIgnore attribute conditional analog but not ShouldSerialize

This is an interesting problem. My answer borrows heavily from the link you provided, but checks for a custom attribute defining your "Premium Content" (things that the user paid for):

Like your link, I have defined a class Foo, which will be serialized. It contains a child object PremiumStuff, which contains things that should only be serialized if the user paid for them. I have marked this child object with a custom attribute PremiumContent, which is also defined in this code snippet. I then used a custom class that inherits from DefaultContractResolver just like the link did, but in this implementation, I am checking each property for our custom attribute, and running the code in the if block only if the property is marked as PremiumContent. This conditional code checks a static bool called AllowPremiumContent to see whether we are allowing the premium content to be serialized. If it is not allowed, then we are setting the Ignore flag to true:

class Foo
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
public string AlternateName { get; set; }
[PremiumContent]
public PremiumStuff ExtraContent { get; set; }
}

class PremiumStuff
{
public string ExtraInfo { get; set; }
public string SecretInfo { get; set; }
}

class IncludePremiumContentAttributesResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
foreach (var prop in props)
{
if (Attribute.IsDefined(type.GetProperty(prop.PropertyName), typeof(PremiumContent)))
{
//if the attribute is marked with [PremiumContent]

if (PremiumContentRights.AllowPremiumContent == false)
{
prop.Ignored = true; // Ignore this if PremiumContentRights.AllowPremiumContent is set to false
}
}
}
return props;
}
}

[System.AttributeUsage(System.AttributeTargets.All)]
public class PremiumContent : Attribute
{
}

public static class PremiumContentRights
{
public static bool AllowPremiumContent = true;
}

Now, let's implement this and see what we get. Here is my test code:

PremiumContentRights.AllowPremiumContent = true;
Foo foo = new Foo()
{
Id = 1,
Name = "Hello",
AlternateName = "World",
ExtraContent = new PremiumStuff()
{
ExtraInfo = "For premium",
SecretInfo = "users only."
}
};

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ContractResolver = new IncludePremiumContentAttributesResolver();
settings.Formatting = Formatting.Indented;

string json = JsonConvert.SerializeObject(foo, settings);

Debug.WriteLine(json);

In the first line, PremiumContentRights.AllowPremiumContent is set to true, and here is the output:

{
"Id": 1,
"Name": "Hello",
"ExtraContent": {
"ExtraInfo": "For premium",
"SecretInfo": "users only."
}
}

If we set AllowPremiumContent to False and run the code again, here is the output:

{
"Id": 1,
"Name": "Hello"
}

As you can see, the ExtraContent property is included or ignored depending on the state of the AllowPremiumContent variable.

Is it possible to JSON Serialize a property marked as [Ignore] automatically

I guess one way to do this is add the ignored fields back:

JsonConvert.DeserializeObject<Contact>(clone).Name=contact.Name

But the point of using ignore is so that it doesn't get serialized.

Another option is to specify a custom contract resolver in jsonserializersettings:

 var deserializeSettings = new JsonSerializerSettings
{
ObjectCreationHandling = ObjectCreationHandling.Replace,
ContractResolver = new DynamicContractResolver()
};

https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Serialization_IContractResolver.htm

public class DynamicContractResolver: DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);

//property.HasMemberAttribute = true;
property.Ignored = false;

//property.ShouldSerialize = instance =>
//{
// return true;
//};

return property;
}
}

control [JsonIgnore] in ASP.NET Web API during runtime

I know two way to solve this problem:

  1. You may add additional boolean property (with specific name) into your model. This is solution is very simple, but requires changes to your model.
  2. You may write own IContractResolver. This method is more complex, but more flexible.

Both solutions described here: 'Conditional Property Serialization' http://james.newtonking.com/json/help/index.html?topic=html/ConditionalProperties.htm

Dynamically ignore the properties on class using json.net

Json.NET has the ability to conditionally serialize properties by placing a ShouldSerialize method on a class.

the following link will give details
http://www.newtonsoft.com/json/help/html/conditionalproperties.htm



Related Topics



Leave a reply



Submit