【问题标题】:Serialize object using Json.NET with valid javascript format使用具有有效 javascript 格式的 Json.NET 序列化对象
【发布时间】:2014-12-29 13:07:50
【问题描述】:

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

【问题讨论】:

标签: javascript c# json.net


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    这个问题真的迟到了......但我有同样的问题并且想通了......所以这是我使用处理特定类的自定义转换器的方法。

    显然...您必须非常小心地使用它。输出是 not 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());
        }
    }
    

    【讨论】:

      【解决方案3】:

      JSON 是一种数据序列化格式。您不应该期望序列化格式来序列化函数。

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

      如果您想使用 JSON 序列化程序来输出包含函数和/或 getter/setter 的对象字面量,那么您使用的工具不正确。或者您仍然可以使用它并执行进一步的字符串操作/替换以获得您期望的结果...

      【讨论】:

        【解决方案4】:

        稍微扩展一下:

        @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"}
        

        【讨论】:

          【解决方案5】:

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-07-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多