I'm using Newtownsoft JSON.Net and want to add custom attributes, then have a JSONConverter that deals with these custom attributes. Currently the way to do this is [JsonConverter(typeof(CustomJsonConverter))]. But I don't want this converter to always be called, only when I pass it into JsonConvert.SerializeObject(...). This is because this class is being used by two different paths, one of which needs to modify the JSON based on the properties and the other doesn't.
In other words, I only want these attributes to be considered when I explicitly tell my code to consider them. They should be ignored when Newtonsoft is doing its default serialization. How can I achieve this?
Example:
class Foo {
[CustomAttributeToAddMyExtraProperty]
public int Bar;
[JsonProperty('default')]
public int Baz;
}
If I just use the default Newtonsoft JSON.Net serialize, I should get
{
"Bar":value1,
"default":value2
}
But if I pass in my custom converter explicitly, I should get this:
{
"Bar":value1,
"default":value2,
"MyExtraProperty":value3
}
Notice that the JSON.Net attributes are always used.
UPDATE
I have tried this:
namespace Project1
{
class Class1
{
static void Main()
{
Class2 foo = new Class2();
Console.WriteLine(JsonConvert.SerializeObject(foo, new JsonSerializerSettings() { ContractResolver = new BlahResolver() }));
Console.Read();
}
}
class Class2
{
[Blah]
public int one = 1;
[JsonProperty]
public int two = 2;
[Blah]
public string three = "3";
}
internal class BlahAttribute : Attribute
{
}
class BlahResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
var attr = property.AttributeProvider.GetAttributes(typeof(BlahAttribute), true);
if (attr.Count == 1)
{
property.Converter = new BlahConverter();
}
return property;
}
}
class BlahConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.IsValueType;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return existingValue;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JToken token = JToken.Parse("{ \"foo\":\"a\", \"bar\":34 }");
token.WriteTo(writer);
}
}
}
Output:
{"one":{"foo":"a","bar":34},"two":2,"three":{"foo":"a","bar":34}}
I'm able to successfully identify properties with my custom attribute and redirect them to my custom converter. The issue now is the converter is adding properties as if one is a complex type. I want to add the properties in the top level JSON, not as properties of one.
Output I want:
{"one":1, "foo":"a","bar":34,"two":2,"three":3,"foo":"a","bar":34}
I realize that this has multiple properties with the same name. I don't know if that's valid or not, but eventually the object value will be included in the name (ex. one_foo, one_bar), so you can disregard that.