C
C#5mo ago
Sky

Newtonsoft.JSON ignore a JsonProperty

Hi there! I'm struggling at making my classes to correctly be serialized. I have an interface:
public interface IComponent
{
public ComponentType ComponentType { get; }
public List<IComponent> Children { get; }
public IComponentClickEvent? ClickEvent { get; set; }
public IComponentStyle Style { get; set; }
}
public interface IComponent
{
public ComponentType ComponentType { get; }
public List<IComponent> Children { get; }
public IComponentClickEvent? ClickEvent { get; set; }
public IComponentStyle Style { get; set; }
}
And its implementation:
public class TextComponent : IComponent
{

[JsonProperty("text")]
public string Text { get; set; }
public TextComponent(string text, IComponentStyle? style)
{
if (string.IsNullOrWhiteSpace(text))
throw new System.ArgumentException("Given text cannot be null or empty", nameof(text));

Text = text;
}

[JsonProperty("type"), JsonConverter(typeof(ComponentTypeSerializer))]
public ComponentType ComponentType { get; } = ComponentType.Text;
public string Type { get; } = "text";

[JsonProperty("extra")]
public List<IComponent> Children { get; } = new();

public IComponentClickEvent? ClickEvent { get; set; }
public IComponentStyle Style { get; set; }
}
public class TextComponent : IComponent
{

[JsonProperty("text")]
public string Text { get; set; }
public TextComponent(string text, IComponentStyle? style)
{
if (string.IsNullOrWhiteSpace(text))
throw new System.ArgumentException("Given text cannot be null or empty", nameof(text));

Text = text;
}

[JsonProperty("type"), JsonConverter(typeof(ComponentTypeSerializer))]
public ComponentType ComponentType { get; } = ComponentType.Text;
public string Type { get; } = "text";

[JsonProperty("extra")]
public List<IComponent> Children { get; } = new();

public IComponentClickEvent? ClickEvent { get; set; }
public IComponentStyle Style { get; set; }
}
I'm also using this serializer:
public class ComponentTypeSerializer : JsonConverter<ComponentType>
{
public override void WriteJson(JsonWriter writer, ComponentType value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString().ToLower());
}

public override ComponentType ReadJson(JsonReader reader, Type objectType, ComponentType existingValue, bool hasExistingValue,
JsonSerializer serializer)
{
throw new NotImplementedException("Deserializing ComponentType is not supported.");
}
}
public class ComponentTypeSerializer : JsonConverter<ComponentType>
{
public override void WriteJson(JsonWriter writer, ComponentType value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString().ToLower());
}

public override ComponentType ReadJson(JsonReader reader, Type objectType, ComponentType existingValue, bool hasExistingValue,
JsonSerializer serializer)
{
throw new NotImplementedException("Deserializing ComponentType is not supported.");
}
}
And I'm serializing my value this way:
var settings = new JsonSerializerSettings
{
Converters = new JsonConverter[]
{
new Serializers.ComponentTypeSerializer(),
new Serializers.ComponentColorSerializer()
},
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore,
Formatting = Formatting.None
};
return JsonConvert.SerializeObject(component, settings);
var settings = new JsonSerializerSettings
{
Converters = new JsonConverter[]
{
new Serializers.ComponentTypeSerializer(),
new Serializers.ComponentColorSerializer()
},
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore,
Formatting = Formatting.None
};
return JsonConvert.SerializeObject(component, settings);
However, I am unable to get the type property working! It literally never shows when serializing my class. For instance, I'm getting {"text": "Hello There", "extra":[]} when serializing new TextComponent("Hello There") Can anyone help me about this? Thanks ^.^
11 Replies
The Fog from Human Resources
newtonsoft.json bad switch to the default serializer stuff its way more reliable and saves you trouble in the futur
Sky
SkyOP5mo ago
Ah really? At this point ?
leowest
leowest5mo ago
NSJ is a very old library made when nothing was available... people that worked on it also made System.Text.Json which is a default library you can use in c# which is 1000x faster and better. NSJ should only be used these days with either malformed json or edge cases.
leowest
leowest5mo ago
How to write custom converters for JSON serialization - .NET
Learn how to create custom converters for the JSON serialization classes that are provided in the System.Text.Json namespace.
Sky
SkyOP5mo ago
Gotcha, I'm trying to convert my current code with the system lib, but I cna't get the JsonPropertyName attribute working, am I missing something? ;-;
var options = new JsonSerializerOptions
{
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters =
{
new JsonStringEnumConverter()
},
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
return JsonSerializer.Serialize(component, options);
var options = new JsonSerializerOptions
{
WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
Converters =
{
new JsonStringEnumConverter()
},
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
return JsonSerializer.Serialize(component, options);
public class TextComponent : IComponent
{

[JsonPropertyName("text")]
public string Text { get; set; }
public TextComponent(string text, IComponentStyle? style)
{
if (string.IsNullOrWhiteSpace(text))
throw new ArgumentException("Given text cannot be null or empty", nameof(text));

Text = text;
}

[JsonPropertyName("type")]
public ComponentType ComponentType { get; } = ComponentType.Text;

[JsonPropertyName("extra")]
public List<IComponent> Children { get; } = new();

public IComponentClickEvent? ClickEvent { get; set; }
public IComponentStyle Style { get; set; }
}
public class TextComponent : IComponent
{

[JsonPropertyName("text")]
public string Text { get; set; }
public TextComponent(string text, IComponentStyle? style)
{
if (string.IsNullOrWhiteSpace(text))
throw new ArgumentException("Given text cannot be null or empty", nameof(text));

Text = text;
}

[JsonPropertyName("type")]
public ComponentType ComponentType { get; } = ComponentType.Text;

[JsonPropertyName("extra")]
public List<IComponent> Children { get; } = new();

public IComponentClickEvent? ClickEvent { get; set; }
public IComponentStyle Style { get; set; }
}
And I'm getting {"componentType":"Text","children":[]} Edit: Got it working, I have to specify the implementation's class so it scans the right class' fields
MODiX
MODiX5mo ago
If you have no further questions, please use /close to mark the forum thread as answered
Sky
SkyOP5mo ago
Ah sorry, I got a last one; I have a custom serializer for a type:
public class ComponentStyleConverter : JsonConverter<ComponentStyle>
{

public override ComponentStyle? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException("Deserializing ComponentStyle is not supported.");
}

public override void Write(Utf8JsonWriter writer, ComponentStyle value, JsonSerializerOptions options)
{
writer.WriteStartObject();

if (value.Color != null)
writer.WriteString("color", value.Color.Color);

writer.WriteBoolean("bold", value.Bold);
writer.WriteBoolean("italic", value.Italic);
writer.WriteBoolean("underlined", value.Underlined);
writer.WriteBoolean("strikethrough", value.Strikethrough);
writer.WriteBoolean("obfuscated", value.Obfuscated);

if (value.Insertion != null)
writer.WriteString("insertion", value.Insertion);

writer.WriteEndObject();
}

}
public class ComponentStyleConverter : JsonConverter<ComponentStyle>
{

public override ComponentStyle? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException("Deserializing ComponentStyle is not supported.");
}

public override void Write(Utf8JsonWriter writer, ComponentStyle value, JsonSerializerOptions options)
{
writer.WriteStartObject();

if (value.Color != null)
writer.WriteString("color", value.Color.Color);

writer.WriteBoolean("bold", value.Bold);
writer.WriteBoolean("italic", value.Italic);
writer.WriteBoolean("underlined", value.Underlined);
writer.WriteBoolean("strikethrough", value.Strikethrough);
writer.WriteBoolean("obfuscated", value.Obfuscated);

if (value.Insertion != null)
writer.WriteString("insertion", value.Insertion);

writer.WriteEndObject();
}

}
And its goal is to serialize the fields in the code object, so not in another object with key style as the current code do
{
"text": "Hello, \u00A75world!",
"type": "Text",
"style": {
"color": "#7FFFD4",
"bold": true,
"italic": false,
"underlined": true,
"strikethrough": false,
"obfuscated": false
}
}
{
"text": "Hello, \u00A75world!",
"type": "Text",
"style": {
"color": "#7FFFD4",
"bold": true,
"italic": false,
"underlined": true,
"strikethrough": false,
"obfuscated": false
}
}
And I am looking for something like:
{
"text": "Hello, \u00A75world!",
"type": "Text",

"color": "#7FFFD4",
"bold": true,
"italic": false,
"underlined": true,
"strikethrough": false,
"obfuscated": false
}
{
"text": "Hello, \u00A75world!",
"type": "Text",

"color": "#7FFFD4",
"bold": true,
"italic": false,
"underlined": true,
"strikethrough": false,
"obfuscated": false
}
How can I achieve this? Another question, how can I create my own ignore condition? Basically, if a list field is empty it's ignored
leowest
leowest5mo ago
there should be a [JsonIgnore] attribute I believe but u mean if its empty dont output it to the resulting json right? I think there is a option for that in the settings u add but I dont remember the name unfortunately
leowest
leowest5mo ago
JsonIgnoreCondition Enum (System.Text.Json.Serialization)
Controls how the JsonIgnoreAttribute ignores properties on serialization and deserialization.
leowest
leowest5mo ago
@Sky but do u want that inside your custom converter? because u seem to already have something to handle it
Want results from more Discord servers?
Add your server