简体   繁体   English

使用具有有效JavaScript格式的Json.NET序列化对象

[英]Serialize object using Json.NET with valid javascript format

Does anyone know how to serialize object as the follow code using Json.NET? 有谁知道如何使用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: 结果输出是一个json字符串:

{
  "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): 但我希望它是以下代码(看起来像javascript哈希):

{
  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("}");
    }

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> 

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. 输出的不是 JSON,而是JavaScript文字对象。 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. 最后...根据使用情况,通过允许在用户的浏览器中执行不受信任的javascript,这可能表示巨大的安全漏洞。

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());
    }
}

JSON is a data serialization format. JSON是数据序列化格式。 You shouldn't expect a serialization format to serialize functions. 您不应该期望序列化格式来序列化函数。

In the other hand, JSON property names are surrounded by double quots. 另一方面,JSON属性名称由双引号引起来。 It's still valid JavaScript since you can declare an object literal using JSON notation (of course, JSON stands for JavaScript Object Notation ...!). 它仍然是有效的JavaScript,因为您可以使用JSON表示法声明对象文字(当然, JSON表示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. 如果要使用JSON序列化程序输出包含函数和/或getter / setter的对象文字,则说明您使用的不是正确的工具。 Or you can still use it and perform further string manipulations/replaces to get what you expect like you already did... 或者,您仍然可以使用它并执行进一步的字符串操作/替换以像您已经做的那样获得期望的结果...

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. 绝对不是地球上看起来最美的事物,可能也不是最理想的事物……但是它将从遵循自己接受的命名约定“标准”的ASP.net MVC模型中剔除遵循公认的JSON命名约定的JSON。

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

Will output: 将输出:

{"fooBar":1,"someString":"some value"}

I believe the JRaw class in Newtonsoft.Json.Linq will achieve what your after. 我相信Newtonsoft.Json.Linq中的JRaw类将实现您的目标。

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

Post: How to serialize a function to json (using razor @<text>) 文章: 如何将一个函数序列化为json(使用razor @ <text>)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM