C# Json.Net How to Ignore a Property in Deserialization But Not in Serialization

Making a property deserialize but not serialize with json.net

There are actually several fairly simple approaches you can use to achieve the result you want.

Let's assume, for example, that you have your classes currently defined like this:

class Config
{
public Fizz ObsoleteSetting { get; set; }
public Bang ReplacementSetting { get; set; }
}

enum Fizz { Alpha, Beta, Gamma }

class Bang
{
public string Value { get; set; }
}

And you want to do this:

string json = @"{ ""ObsoleteSetting"" : ""Gamma"" }";

// deserialize
Config config = JsonConvert.DeserializeObject<Config>(json);

// migrate
config.ReplacementSetting =
new Bang { Value = config.ObsoleteSetting.ToString() };

// serialize
json = JsonConvert.SerializeObject(config);
Console.WriteLine(json);

To get this:

{"ReplacementSetting":{"Value":"Gamma"}}
Approach 1: Add a ShouldSerialize method

Json.NET has the ability to conditionally serialize properties by looking for corresponding ShouldSerialize methods in the class.

To use this feature, add a boolean ShouldSerializeBlah() method to your class where Blah is replaced with the name of the property that you do not want to serialize. Make the implementation of this method always return false.

class Config
{
public Fizz ObsoleteSetting { get; set; }

public Bang ReplacementSetting { get; set; }

public bool ShouldSerializeObsoleteSetting()
{
return false;
}
}

Note: if you like this approach but you don't want to muddy up the public interface of your class by introducing a ShouldSerialize method, you can use an IContractResolver to do the same thing programmatically. See Conditional Property Serialization in the documentation.

Approach 2: Manipulate the JSON with JObjects

Instead of using JsonConvert.SerializeObject to do the serialization, load the config object into a JObject, then simply remove the unwanted property from the JSON before writing it out. It's just a couple of extra lines of code.

JObject jo = JObject.FromObject(config);

// remove the "ObsoleteSetting" JProperty from its parent
jo["ObsoleteSetting"].Parent.Remove();

json = jo.ToString();
Approach 3: Clever (ab)use of attributes
  1. Apply a [JsonIgnore] attribute to the property that you do not want to be serialized.
  2. Add an alternate, private property setter to the class with the same type as the original property. Make the implementation of that property set the original property.
  3. Apply a [JsonProperty] attribute to the alternate setter, giving it the same JSON name as the original property.

Here is the revised Config class:

class Config
{
[JsonIgnore]
public Fizz ObsoleteSetting { get; set; }

[JsonProperty("ObsoleteSetting")]
private Fizz ObsoleteSettingAlternateSetter
{
// get is intentionally omitted here
set { ObsoleteSetting = value; }
}

public Bang ReplacementSetting { get; set; }
}

How to ignore a property from serialization but keep in for deserialization using json.net in c#

Could you have a method for the 'set' of Content and process the data into the right place.

public class Foo
{
[JsonProperty("id")]
public int Id { get; set; }

[JsonProperty("contentType")]
public object ContentType { get; set; }

[JsonProperty("content")]
public object Content { get; set {
//do something here with `value` e.g.
RelationshipContent = value; //change as required
DomainContent = value; //change as required
}
}

[JsonIgnore]
public Relationship RelationshipContent { get; set; }

[JsonIgnore]
public Domains DomainContent { get; set; }

}

Ignore some of the properties during Json.NET serializing but required on others

Try the below code

    [JsonProperty(PropertyName = "componentMainVersion", DefaultValueHandling = DefaultValueHandling.Include)] 
public ushort Version { get; set; }

Required is a different property which makes sure that value for the property is required always

Serialize Property, but Do Not Deserialize Property in Json.Net

Simplest method would be to mark the real property as [JsonIgnore] and create a get-only proxy property:

    /// <summary>
/// Gets or sets the country code, and province or state code delimited by a vertical pipe: <c>US|MI</c>
/// </summary>
[JsonIgnore]
public string CountryProvinceState
{
get
{
return string.Format("{0}|{1}", this.CountryCode, this.ProvinceState);
}
set
{
if (!string.IsNullOrWhiteSpace(value) && value.Contains("|"))
{
string[] valueParts = value.Split('|');
if (valueParts.Length == 2)
{
this.CountryCode = valueParts[0];
this.ProvinceState = valueParts[1];
}
}
}
}

[JsonProperty("countryProvinceState")]
string ReadCountryProvinceState
{
get { return CountryProvinceState; }
}

The proxy property can be private if you desire.

Update

If you have to do this for lots of properties in lots of classes, it might be easier to create your own ContractResolver that checks for a custom attribute. If found, the attribute would signal that the property is get-only:

[System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple = false)]
public class GetOnlyJsonPropertyAttribute : Attribute
{
}

public class GetOnlyContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (property != null && property.Writable)
{
var attributes = property.AttributeProvider.GetAttributes(typeof(GetOnlyJsonPropertyAttribute), true);
if (attributes != null && attributes.Count > 0)
property.Writable = false;
}
return property;
}
}

Then use it like:

[JsonProperty("countryProvinceState")]
[GetOnlyJsonProperty]
public string CountryProvinceState { get; set; }

And then:

        var settings = new JsonSerializerSettings { ContractResolver = new GetOnlyContractResolver() };

var address = JsonConvert.DeserializeObject<Address>(jsonString, settings);

Ignore a property when deserializing using Json.Net with ItemRequired = Required.Always

Evidently JsonIgnore will only control the serialization in this case. JsonIgnore is required to specify that the FullName property should not be serialized to the json representation.

To ignore the property during deserialization we need to add the JsonProperty annotation with Required = Required.Default (which means not required).

So, this is how to avoid the JsonSerializationException:

[JsonObject(ItemRequired = Required.Always)]
public class Hamster
{
public string FirstName { get; set; }
public string LastName { get; set; }
[JsonIgnore]
[JsonProperty(Required = Required.Default)]
public string FullName { get { return FirstName + LastName; }}
}

Can I instruct Json.NET to deserialize, but not serialize, specific properties?

You should be able to just use the ShouldSerialize* methods as shown in the question. These only impact serialization, not deserialization.

Json Serialize ignore properties when not assigning value but property should be present when assign null

To be more generic you have to create your own ContractResolver class

Step 1: Car class should be as following:

public class Car {
public int CarId { get; set; }
public string Brand { get; set; } = "null"; // Default value
public string Model { get; set; } = "null"; // Default value
public string Color { get; set; } = "null"; // Default value
}

Step 2: You will need to create the following class:

public class ShouldSerializeContractResolver : DefaultContractResolver {
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (!property.PropertyName.Equals("CarId")) {
property.ShouldSerialize =
instance => {
var car = (Car)instance;
var value = car.GetType().GetProperty(property.PropertyName).GetValue(car, null);
return value == null || !value.ToString().Equals("null");
};
}
return property;
}
}

Step 3: create car object:

var car = new Car {
CarId = 1,
Brand = "Hundai",
Model = null
};

Step 4: Serialize the object - Notice how we create ContractResolver here :

var SerializedCar = JsonConvert.SerializeObject(car, 
Formatting.Indented,
new JsonSerializerSettings {ContractResolver = new ShouldSerializeContractResolver()
});

Step 5: Print the output:

Console.WriteLine(SerializedCar);

Finally: The result:

   {
"CarId": 1,
"Brand": "Hundai",
"Model": null
}


Related Topics



Leave a reply



Submit