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

Serialize object using Json.NET with valid javascript format

本文关键字:Json NET 序列化 对象 格式 JavaScript 有效      更新时间:2023-09-26

>有谁知道如何使用 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));
    }
}

结果输出是一个 json 字符串:

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

但我希望它为以下代码(它看起来像javascript哈希):

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

下面的代码将按我预期显示输出。但我需要一个不同的解决方案。请帮助我。谢谢

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

如果要将某些内容输出到将运行脚本的网页,则可以执行以下操作:

<script>
  var myThing = eval( @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(dic, Formatting.Indented)) );
</script>

这个问题

真的晚了...但我有同样的一个并想通了...所以这是我如何使用处理特定类的自定义转换器来做到这一点的。

明显地。。。你必须非常小心地使用它。输出不是 JSON,而是一个 JavaScript 文字对象。此外,函数声明没有内置的转义,因此破坏整体文本对象语法是微不足道的。最后。。。根据使用情况,这可能代表一个巨大的安全漏洞,因为它允许在用户的浏览器中执行不受信任的JavaScript。

代码如下:

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 是一种数据序列化格式。不应期望序列化格式来序列化函数。

另一方面,JSON 属性名称用双引号括起来。它仍然是有效的JavaScript,因为您可以使用JSON表示法声明对象文字(当然,JSON代表JavaScript对象表示法...!)。

如果要使用 JSON 序列化程序输出包含函数和/或 getter/setter 的对象文本,则没有使用正确的工具。或者您仍然可以使用它并执行进一步的字符串操作/替换,以获得您所期望的,就像您已经做过的那样......

只是扩展一下:

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

绝对不是地球上最好看的东西,也可能不是那么理想......但它会从遵循自己接受的命名约定"标准"的 ASP.net MVC 模型中剔除遵循已接受 JSON 命名约定的 JSON。

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

将输出:

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

我相信Newtonsoft.Json.Linq中的JRaw类将实现您的追求。

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

发布:如何将函数序列化为 json(使用 razor @