Search code examples
c#.net-4.0json.netobject-to-string

Remove Json specific node


during run time I'd like to print JSon to log but censor one of its fields. I use JSon.Net and have all the attributes, for example

    public Class Terms
    {
        [JsonProperty("Term")]
        string term

        [JsonProperty("SecretTerm")]
        string SecretTerm

        public string toCensoredString()
        {
         // I need to get a JSON string with only the regular term and not the secret
         var jsonRequest = JsonConvert.SerializeObject(this);
         // .....
        }
    }

What will be the best way to eliminate specific field in runtime in my new ToCensoredString() function?


Solution

  • By far the easiest approach is to use the JsonIgnore attribute.

    If I create a Terms object like this:

    Terms terms = new Terms() { SecretTerm = "Secret", Term = "Not secret" };
    

    And if SecretTerm looks like this:

    [JsonIgnore]
    [JsonProperty("SecretTerm")]
    public string SecretTerm { get; set; }
    

    Your serialized Json will look like this:

    {
        "Term": "Not secret"
    }
    

    If you want more fine-grained control you will have to create a custom converter.

    Edit:

    To more selectively output the object, you need the custom converter:

    class TermsConverter : Newtonsoft.Json.JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(Terms) == objectType;
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            Terms terms = (Terms)value;
    
            writer.WriteStartObject();
            writer.WritePropertyName("Term");
            writer.WriteValue(terms.Term);
            writer.WriteEndObject();
        }
    }
    

    When serializing, you would do this:

    var jsonRequest = JsonConvert.SerializeObject(this, new TermsConverter());
    

    You'll note that I have left the ReadJson unimplemented - I don't think it's necessary as you can easily deserialize a Terms object without using a converter. In this case the SecretTerm property would simply be empty.

    By using the converter you won't need the [JsonIgnore] attribute on the SecretTerm property.