【问题标题】:Serializing strings containing apostrophes with JSON.Net使用 JSON.Net 序列化包含撇号的字符串
【发布时间】:2012-08-20 17:35:38
【问题描述】:

我使用 JSON.Net 作为 c# 中的大型 MVC 3 Web 应用程序和 Razor 视图引擎的序列化程序。对于一个视图中的初始页面加载,使用@Html.Raw(JsonConvert.SerializeObject(myObject)) 在脚本标签中转储了大量 JSON。

问题是某些对象的某些值包含撇号(想想像 O'Brien 这样的名字),JSON.Net 不会以任何方式转义或编码。

不可以对存储在数据库中的值进行预编码,因为这会使其他各种过程变得非常复杂。

有没有办法强制 JSON.Net 对其序列化的对象的值进行 HTML 编码,就像调用 JavaScriptSerializer.Serialize(myObject) 时内置的 JavaScriptSerializer 所做的一样?或者,有没有办法在视图中处理这个问题?

【问题讨论】:

  • 因为 JSON 坚持对字符串使用双引号字符,所以单引号字符没有问题,也不需要转义。
  • 这是不真实的。当您将 JSON 转储到 HTML 页面时,JSON 字符串本身用单引号或双引号括起来,这将使您用来包装字符串的任何字符在 JSON 本身中不可用。这就是问题的症结所在。
  • 好吧,如果您将 JSON 作为 string 进行“转储”,那将是一个问题。你为什么不把它作为 JavaScript 放在页面上 - 换句话说,没有任何额外的引号?否则,您可以只使用正则表达式来引用单引号。
  • 这就是解决方案。正如您所指出的,没有必要将其作为字符串放入页面中。将该回复作为答案,我会接受。
  • 嗯,这似乎是一个不错的猜测 :-) 我会输入的。

标签: c# javascript json asp.net-mvc-3 json.net


【解决方案1】:
JsonSerializerSettings settings = new JsonSerializerSettings
{
    StringEscapeHandling = StringEscapeHandling.EscapeHtml
};

JsonConvert.SerializeObject(obj, settings);

【讨论】:

    【解决方案2】:

    虽然在某些情况下您可能希望将一些 JSON 作为 JavaScript 字符串或 HTML 属性值放入您的页面,但通常您要做的只是将其直接包含到 JavaScript 源代码中,因为 JSON 是有效的毕竟是 JavaScript 语法。

    【讨论】:

    • 正确!这意味着不是做这样的事情,例如: var myObject = JSON.parse('@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.MyObject))');这样做: var myObject = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.MyObject));
    【解决方案3】:

    您可以像这样创建自定义 JsonConverter:

    public class EscapeQuoteConverter : JsonConverter 
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
        {
            writer.WriteValue(value.ToString().Replace("'", "\\'"));
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
        {
            var value = JToken.Load(reader).Value<string>();
            return value.Replace("\\'", "'");
        }
    
        public override bool CanConvert(Type objectType) 
        {
            return objectType == typeof(string);
        }
    }
    

    仅将其用于 Name 属性,请通过属性指定它:

    public class Person 
    {
        [JsonConverter(typeof(EscapeQuoteConverter))]
        public string Name { get; set; } 
    }
    

    要将 Converter 应用于所有字符串,请使用:

    JsonConvert.SerializeObject(person, Formatting.Indented, new EscapeQuoteConverter());
    

    【讨论】:

    • 这是一个简洁的机制。感谢那。不过,Pointy 的评论是我需要的“你做错了”。比一个答案,我会标记它是正确的。
    • 这对于修复破坏我的 sql 语句的单引号很有用。我只是将替换部分更改为 Replace("'", "''")。
    【解决方案4】:

    使用System.Web.HttpUtility.HtmlEncode

    HttpUtility.HtmlEncode(JsonConvert.SerializeObject(myObject))
    

    【讨论】:

    • 谢谢,虽然这不能回答这里提出的问题,但它确实回答了我在 Google 上提出的问题,这是第一个结果。
    猜你喜欢
    • 2012-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多