21

Is it possible to tell JSON.NET I have a string with JSON data? E.g. I have a class like this:

public class Foo
{
    public int Id;
    public string RawData;
}

which I use like this:

var foo = new Foo();
foo.Id = 5;
foo.RawData = @"{""bar"":42}";

which I want to be serialized like this:

{"Id":5,"RawData":{"bar":42}}

Basically I have a piece of unstructured variable-length data stored as JSON already, I need fully serialized object to contain this data as a part.

Thanks.

EDIT: Just to make sure it is understood properly, this is one-way serialization, i.e. I don't need it to deserialize back into same object; the other system shall process this output. I need content of RawData to be a part of JSON, not a mere string.

port443
  • 561
  • 1
  • 4
  • 12
  • yes it is possible, but can you tell me exactly what is the output you need? currently it is: {"Id":5,"RawData":"{\"bar\":42}"} –  Jul 11 '13 at 04:36
  • @Rivers, this is exactly what I need. I have a string property with JSON content which I think is useless to deserialize just for the purpose of serializing it back to JSON. – port443 Jul 11 '13 at 12:27
  • @Rivers, sorry, I didn't read your example well enough. In your case content of RawData in JSON is string, I need it to be a sub-object (i.e. your variant has extra quotes and backslashes added. – port443 Jul 11 '13 at 13:15

3 Answers3

23

You need a converter to do that, here is an example:

public class RawJsonConverter : JsonConverter
{
   public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
   {
       writer.WriteRawValue(value.ToString());
   }

   public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
   {
        using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture)) 
        {
            using (var jsonTextWriter = new JsonTextWriter(stringWriter))
            {
                jsonTextWriter.WriteToken(reader);
                var result = stringWriter.ToString();
                return result;
            }
        }
   }

   public override bool CanConvert(Type objectType)
   {
       return typeof(string).IsAssignableFrom(objectType);
   }
   
   public override bool CanRead
   {
       get { return true; }
   }   
}

Then decorate your class with it:

public class Foo
{
    public int Id;
    [JsonConverter(typeof(RawJsonConverter))]
    public string RawData;
}

Then, when you use:

var json = JsonConvert.SerializeObject(foo,
                                    new JsonSerializerSettings());
Console.WriteLine (json);

This is your output:

{"Id":5,"RawData":{"bar":42}}

Hope it helps

Edit: I have updated my answer for a more efficient solution, the previous one forced you to serialize to then deserialize, this doesn't.

Edit, 5/11/2023: Changed JsonConverter to also support deserialization.

pettys
  • 2,293
  • 26
  • 38
7

It is possible, that using JRaw could be more suitable and compact solution

See this post

David Gardiner
  • 16,892
  • 20
  • 80
  • 117
Alexus1024
  • 447
  • 5
  • 7
4

You can use another property to deserialize the object property json.

public class Foo
{
    public int Id;
    public string RawData;
    private object thisObject;
    public object ThisObject 
    {
        get
        {
            return thisObject ?? (thisObject = JsonConvert.DeserializeObject<object>(RawData));
        }
    }        
}
Tarek Ayna
  • 340
  • 4
  • 10