0

Does anyone know how to serialize object as the follow code using Json.NET?

class Program
{
    static void Main(string[] args)
    {
        var dic = new Dictionary<string, object>();
        dic.Add("key", true);
        dic.Add("create", false);
        dic.Add("title", "Name");
        dic.Add("option2", @"function(value){ return value; }");
        dic.Add("fields", new Dictionary<string, object>
        {
            {"Id", new Dictionary<string, object>
                   {
                       {"title", "This is id"}
                   }
            }
        });
        Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(dic, Formatting.Indented));
    }
}

Result output is a json string:

{
  "key": true,
  "create": false,
  "title": "Name",
  "option2": "function(value){ return value; }",
  "fields": {
    "Id": {
      "title": "This is id"
    }
  }
}

But I expect it as the following code (it looks like javascript hash):

{
  key: true,
  create: false,
  title: "Name",
  option2: function(value){ return value; },
  fields: {
    Id: {
      title: "This is id"
    }
  }
}

The below code will show the output as I expect. But I need a different solution. Please help me. Thank you

    private static void SerializeObject(IDictionary<string, object> dic)
    {
        Console.WriteLine("{");
        foreach (var key in dic.Keys)
        {
            var value = dic[key];
            if (value is JsFunction)  // just a wrapper class of string
            {
                Console.WriteLine("{0}: {1}", key, value);
            }
            else if (value is IDictionary<string, object>)
            {
                Console.WriteLine("{0}:", key);
                SerializeObject(value as IDictionary<string, object>);
            }
            else
            {
                Console.WriteLine("{0}: {1}", key, JsonConvert.SerializeObject(dic[key]));
            }
        }
        Console.WriteLine("}");
    }
Martinez
  • 172
  • 4
  • 17
  • 7
    Your expected notation is invalid JSON. – Jeroen Vannevel Dec 29 '14 at 13:10
  • Yes, I use it as javascript variable. So invalid JSON is not a problem – Martinez Dec 29 '14 at 13:13
  • 2
    So your question is more about how to generate a javascript rather then serializing to json... This question can be interesting for you [Parsing functions stored as strings in object literal/JSON syntax and differetiating](http://stackoverflow.com/questions/16767431/parsing-functions-stored-as-strings-in-object-literal-json-syntax-and-differetia) – t3chb0t Dec 30 '14 at 09:52

5 Answers5

2

If you're outputting something to a web page that will be running the script, you could do something like this:

<script>
  var myThing = eval( @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(dic, Formatting.Indented)) );
</script>
GeekyMonkey
  • 12,478
  • 6
  • 33
  • 39
1

Really late to this question... but I had the same one and figured it out... so here's how I did it using a custom converter that handles a specific class.

OBVIOUSLY... you have to be very careful using this. The output is not JSON, rather it is a JavaScript literal object. Further the function declaration has no built in escaping so it is trivial to break the overall literal object syntax. Lastly... depending on use this could represent a giant security hole by allowing untrusted javascript to be executed in a user's browser.

Here's the code:

class Program
{
    static void Main(string[] args)
    {
        var swc = new SomethingWithCode { 
                      JustSomething = "hello", 
                      FuncDeclaration = "function() { alert('here'); }" 
        };

        var serializer = new Newtonsoft.Json.JsonSerializer();
        serializer.Converters.Add(new FunctionJsonConverter());
        serializer.NullValueHandling = Newtonsoft.Json.NullValueHandling.Include;

        using (var sw = new System.IO.StringWriter())
        {
            using (var writer = new Newtonsoft.Json.JsonTextWriter(sw))
            {
                serializer.Serialize(writer, swc);
            }

            Console.Write(sw.ToString());
        }
    }
}

class SomethingWithCode
{
    public string JustSomething { get; set; }
    public JavaScriptFunctionDeclaration FuncDeclaration { get; set; }
}

class JavaScriptFunctionDeclaration
{
    private string Code;

    public static implicit operator JavaScriptFunctionDeclaration(string value)
    {
        return new JavaScriptFunctionDeclaration { Code = value };
    }

    public override string ToString()
    {
        return this.Code;
    }
}

class FunctionJsonConverter : Newtonsoft.Json.JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(JavaScriptFunctionDeclaration);
    }

    public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
    {
        writer.WriteRawValue(value.ToString());
    }
}
user2845090
  • 147
  • 3
  • 14
0

JSON is a data serialization format. You shouldn't expect a serialization format to serialize functions.

In the other hand, JSON property names are surrounded by double quots. It's still valid JavaScript since you can declare an object literal using JSON notation (of course, JSON stands for JavaScript Object Notation...!).

If you want to use a JSON serializer to output an object literal containing functions and/or getters/setters, you're not using the right tool. Or you can still use it and perform further string manipulations/replaces to get what you expect like you already did...

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206
0

Just extending a bit:

@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(
    Model,
    new Newtonsoft.Json.JsonSerializerSettings{ ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()}
));

Definitely not the best looking thing on the planet and probably not that optimal... BUT it will barf out JSON that follows accepted JSON naming conventions from an ASP.net MVC model that follows it's own accepted "standards" for naming conventions.

...
public int FooBar { get; set; }
public string SomeString { get; set; }
...

Will output:

{"fooBar":1,"someString":"some value"}
nokturnal
  • 2,809
  • 4
  • 29
  • 39
0

I believe the JRaw class in Newtonsoft.Json.Linq will achieve what your after.

   @using Newtonsoft.Json.Linq;
   ........
   dic.Add("option2", new JRaw("function(value){ return value; }"));

Post: How to serialize a function to json (using razor @<text>)

Community
  • 1
  • 1
Norf
  • 35
  • 6