Сериализация строк, содержащих апострофы с помощью JSON.Net

Я использую JSON.Net в качестве своего сериализатора для большого веб-приложения MVC 3 в С# и механизма просмотра Razor. Для начальной загрузки страницы в одном представлении большое количество JSON сбрасывается внутри тега script, используя @Html.Raw(JsonConvert.SerializeObject(myObject)).

Проблема заключается в том, что некоторые значения некоторых объектов содержат апострофы (например, имена O'Brien), которые JSON.Net никак не экранирует или кодирует.

Это не вариант предварительного кодирования значений, хранящихся в базе данных, поскольку это значительно усложняет различные другие процессы.

Есть ли способ заставить JSON.Net для HTML кодировать значения объектов, которые он сериализует, так же, как это делает встроенный JavaScriptSerializer при вызове JavaScriptSerializer.Serialize(myObject)? Или, есть ли способ справиться с этим в представлении?

Ответы

Ответ 1

Хотя есть некоторые случаи, когда вы можете отбросить некоторые JSON на свою страницу в виде строки JavaScript или значение атрибута HTML, чаще всего то, что вы делаете, просто включает его непосредственно в исходный код JavaScript, поскольку JSON действителен Синтаксис JavaScript в конце концов.

Ответ 2

JsonSerializerSettings settings = new JsonSerializerSettings
{
    StringEscapeHandling = StringEscapeHandling.EscapeHtml
};

JsonConvert.SerializeObject(obj, settings);

Ответ 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; } 
}

Чтобы применить конвертер ко всем строкам, используйте:

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