web-dev-qa-db-fra.com

Sérialisation de chaînes contenant des apostrophes avec JSON.Net

J'utilise JSON.Net comme sérialiseur pour une grande application Web MVC 3 en c # et le moteur de visualisation Razor. Pour le chargement de page initial dans une vue, il y a une grande quantité de JSON vidé dans une balise de script à l'aide de @Html.Raw(JsonConvert.SerializeObject(myObject)).

Le problème est que certaines valeurs de certains objets contiennent des apostrophes (pensez à des noms comme O'Brien), que JSON.Net n'échappe ni n'encode d'aucune façon.

Ce n'est pas une option pour pré-encoder les valeurs stockées dans la base de données car cela complique considérablement divers autres processus.

Existe-t-il un moyen de forcer JSON.Net à coder HTML les valeurs des objets qu'il sérialise, de la même manière que le JavaScriptSerializer intégré le fait lorsque vous appelez JavaScriptSerializer.Serialize(myObject)? Ou, existe-t-il un moyen de traiter cela dans la vue?

20
dodexahedron

Bien qu'il y ait des cas où vous voudrez peut-être déposer du JSON dans votre page en tant que chaîne JavaScript ou en tant que valeur d'attribut HTML, le plus souvent ce que vous feriez serait simplement de l'inclure directement dans la source JavaScript, car JSON est une syntaxe JavaScript valide après tout.

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

JsonConvert.SerializeObject(obj, settings);
26
rrymar

Vous pouvez créer un JsonConverter personnalisé comme ceci:

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

Pour l'utiliser uniquement pour la propriété Name, spécifiez-la par attribut:

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

Pour appliquer Converter à toutes les chaînes, utilisez:

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

Utilisez System.Web.HttpUtility.HtmlEncode

HttpUtility.HtmlEncode(JsonConvert.SerializeObject(myObject))
3
Preston S