J'ai utilisé ceci pour éviter le manque System.Web.Helpers.Json.Encodedans VS2015, mais il a besoin du (input, true)paramètre pour inclure également les citations réelles.
lapo
47
Pour ceux qui utilisent le très populaire projet Json.Net de Newtonsoft, la tâche est triviale:
using Newtonsoft.Json;....var s =JsonConvert.ToString(@"a\b");Console.WriteLine(s);....
Ce code imprime:
"un B"
Autrement dit, la valeur de chaîne résultante contient les guillemets ainsi que la barre oblique inverse échappée.
Je ne peux pas reproduire cette méthode pour désérialiser un chemin unc encodé et échappé. Mon chemin "WatchedPath": "\\\\myserver\\output"devient "\"\\\\\\\\myserver\\\\output\""ce qui est assez inacceptable.
slestak
3
La méthode ci-dessus n'est pas pour la désérialisation - rater, elle est utilisée lorsque vous souhaitez créer un texte JSON manuellement et que vous avez une chaîne C # et que vous devez obtenir sa représentation correcte sous forme de texte.
Dror Harari
@slestak, je pense que je suis confronté au même problème que vous étiez ici. Avez-vous trouvé une solution?
GP24
@ GP24 IIRC, je ne l'ai pas fait. Désolé je n'ai plus d'informations.
slestak
Pas de problème, merci d'avoir répondu. Je l'ai fait si cela vous aide: yourAnnoyingDoubleEncodedString.Replace ("\\\\", "\\"). Replace ("\\\" "," \ "");
Je sais que c'est une vieille réponse et je suis heureux de voir que cela a été donné car je ne voulais pas me fier à des bibliothèques externes, mais j'ai remarqué que la casse par défaut pour un caractère de contrôle retournera toujours "\\ u000X". Je crois que vous devez d'abord convertir le caractère en un int. Pensez à le remplacer parstring t = "000" + ((int)c).ToString("X");
Jan Discart
La casse par défaut correcte doit être:t = "000" + String.Format("{0:X}",(int) c);
daniatic le
16
J'ai utilisé le code suivant pour échapper à la valeur de chaîne pour json. Vous devez ajouter votre "" "à la sortie du code suivant:
Cela m'a vraiment sauvé la journée. Merci beaucoup!
casaout
8
N'utilisez pas ce code en production! Cet échappement JSON manque des caractères spéciaux importants. Voir: stackoverflow.com/a/33799784
vog
2
Ce code ne couvre pas tous les cas particuliers. NE PAS utiliser en production.
Envil
2
réinventer la roue, et introduire un bug dans des cas particuliers, n'est pas une bonne réponse
Xilmiki
6
Les méthodes proposées ici sont défectueuses.
Pourquoi s'aventurer aussi loin alors que vous pourriez simplement utiliser System.Web.HttpUtility.JavaScriptEncode?
Si vous êtes sur un framework inférieur, vous pouvez simplement le copier-coller à partir du mono
publicstaticstringJavaScriptStringEncode(stringvalue,bool addDoubleQuotes){if(string.IsNullOrEmpty(value))return addDoubleQuotes ?"\"\"":string.Empty;int len =value.Length;bool needEncode =false;char c;for(int i =0; i < len; i++){
c =value[i];if(c >=0&& c <=31|| c ==34|| c ==39|| c ==60|| c ==62|| c ==92){
needEncode =true;break;}}if(!needEncode)return addDoubleQuotes ?"\""+value+"\"":value;var sb =newSystem.Text.StringBuilder();if(addDoubleQuotes)
sb.Append('"');for(int i =0; i < len; i++){
c =value[i];if(c >=0&& c <=7|| c ==11|| c >=14&& c <=31|| c ==39|| c ==60|| c ==62)
sb.AppendFormat("\\u{0:x4}",(int)c);elseswitch((int)c){case8:
sb.Append("\\b");break;case9:
sb.Append("\\t");break;case10:
sb.Append("\\n");break;case12:
sb.Append("\\f");break;case13:
sb.Append("\\r");break;case34:
sb.Append("\\\"");break;case92:
sb.Append("\\\\");break;default:
sb.Append(c);break;}}if(addDoubleQuotes)
sb.Append('"');return sb.ToString();}
Cela peut être compacté en
// https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cspublicclassSimpleJSON{privatestaticboolNeedEscape(string src,int i){char c = src[i];return c <32|| c =='"'|| c =='\\'// Broken lead surrogate||(c >='\uD800'&& c <='\uDBFF'&&(i == src.Length-1|| src[i +1]<'\uDC00'|| src[i +1]>'\uDFFF'))// Broken tail surrogate||(c >='\uDC00'&& c <='\uDFFF'&&(i ==0|| src[i -1]<'\uD800'|| src[i -1]>'\uDBFF'))// To produce valid JavaScript|| c =='\u2028'|| c =='\u2029'// Escape "</" for <script> tags||(c =='/'&& i >0&& src[i -1]=='<');}publicstaticstringEscapeString(string src){System.Text.StringBuilder sb =newSystem.Text.StringBuilder();int start =0;for(int i =0; i < src.Length; i++)if(NeedEscape(src, i)){
sb.Append(src, start, i - start);switch(src[i]){case'\b': sb.Append("\\b");break;case'\f': sb.Append("\\f");break;case'\n': sb.Append("\\n");break;case'\r': sb.Append("\\r");break;case'\t': sb.Append("\\t");break;case'\"': sb.Append("\\\"");break;case'\\': sb.Append("\\\\");break;case'/': sb.Append("\\/");break;default:
sb.Append("\\u");
sb.Append(((int)src[i]).ToString("x04"));break;}
start = i +1;}
sb.Append(src, start, src.Length- start);return sb.ToString();}}
Je recommanderais également d'utiliser la bibliothèque JSON.NET mentionnée, mais si vous devez échapper des caractères unicode (par exemple au format \ uXXXX) dans la chaîne JSON résultante, vous devrez peut-être le faire vous-même. Jetez un œil à la conversion de chaînes Unicode en chaîne ascii échappée pour un exemple.
J'ai effectué des tests de vitesse sur certaines de ces réponses pour une longue chaîne et une courte chaîne. Le code de Clive Paterson a bien gagné, probablement parce que les autres prennent en compte les options de sérialisation. Voici mes résultats:
publicstaticvoidMain(string[] args){var testStr1 ="Apple Banana";var testStr2 =@"\\some\long\path\with\lots\of\things\to\escape\some\long\path\t\with\lots\of\n\things\to\escape\some\long\path\with\lots\of\""things\to\escape\some\long\path\with\lots""\of\things\to\escape";foreach(var testStr innew[]{ testStr1, testStr2 }){var results =newDictionary<string,List<long>>();for(var n =0; n <10; n++){var count =1000*1000;var sw =Stopwatch.StartNew();for(var i =0; i < count; i++){var s =System.Web.HttpUtility.JavaScriptStringEncode(testStr);}var t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.HttpUtility.JavaScriptStringEncode").Add(t);
sw =Stopwatch.StartNew();for(var i =0; i < count; i++){var s =System.Web.Helpers.Json.Encode(testStr);}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("System.Web.Helpers.Json.Encode").Add(t);
sw =Stopwatch.StartNew();for(var i =0; i < count; i++){var s =Newtonsoft.Json.JsonConvert.ToString(testStr);}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Newtonsoft.Json.JsonConvert.ToString").Add(t);
sw =Stopwatch.StartNew();for(var i =0; i < count; i++){var s = cleanForJSON(testStr);}
t = sw.ElapsedMilliseconds;
results.GetOrCreate("Clive Paterson").Add(t);}Console.WriteLine(testStr);foreach(var result in results){Console.WriteLine(result.Key+": "+Math.Round(result.Value.Skip(1).Average())+"ms");}Console.WriteLine();}Console.ReadLine();}
J'ai une belle ligne, j'ai utilisé JsonConvert comme d'autres l'ont fait, mais j'ai ajouté une sous-chaîne pour supprimer les guillemets ajoutés et la barre oblique inverse.
var escapedJsonString =JsonConvert.ToString(JsonString).Substring(1,JsonString.Length-2);
Réponses:
j'utilise
System.Web.HttpUtility.JavaScriptStringEncode
la source
System.Web.Helpers.Json.Encode
dans VS2015, mais il a besoin du(input, true)
paramètre pour inclure également les citations réelles.Pour ceux qui utilisent le très populaire projet Json.Net de Newtonsoft, la tâche est triviale:
Ce code imprime:
"un B"
Autrement dit, la valeur de chaîne résultante contient les guillemets ainsi que la barre oblique inverse échappée.
la source
"WatchedPath": "\\\\myserver\\output"
devient"\"\\\\\\\\myserver\\\\output\""
ce qui est assez inacceptable.En vous basant sur la réponse de Dejan , vous pouvez importer
System.Web.Helpers
l'assembly .NET Framework , puis utiliser la fonction suivante:L'
Substring
appel est obligatoire, carEncode
entoure automatiquement les chaînes de guillemets.la source
Oui, ajoutez simplement la fonction suivante à votre classe Utils ou quelque chose:
la source
/
?string t = "000" + ((int)c).ToString("X");
t = "000" + String.Format("{0:X}",(int) c);
J'ai utilisé le code suivant pour échapper à la valeur de chaîne pour json. Vous devez ajouter votre "" "à la sortie du code suivant:
la source
Les méthodes proposées ici sont défectueuses.
Pourquoi s'aventurer aussi loin alors que vous pourriez simplement utiliser System.Web.HttpUtility.JavaScriptEncode?
Si vous êtes sur un framework inférieur, vous pouvez simplement le copier-coller à partir du mono
Gracieuseté du mono-projet @ https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs
Cela peut être compacté en
la source
Je recommanderais également d'utiliser la bibliothèque JSON.NET mentionnée, mais si vous devez échapper des caractères unicode (par exemple au format \ uXXXX) dans la chaîne JSON résultante, vous devrez peut-être le faire vous-même. Jetez un œil à la conversion de chaînes Unicode en chaîne ascii échappée pour un exemple.
la source
J'ai effectué des tests de vitesse sur certaines de ces réponses pour une longue chaîne et une courte chaîne. Le code de Clive Paterson a bien gagné, probablement parce que les autres prennent en compte les options de sérialisation. Voici mes résultats:
Et voici le code de test:
la source
Qu'en est-il de System.Web.Helpers.Json.Encode (...) (voir http://msdn.microsoft.com/en-us/library/system.web.helpers.json.encode(v=vs.111) .aspx )?
la source
Cela sort juste: X
Essayez plutôt ceci:
la source
J'ai une belle ligne, j'ai utilisé JsonConvert comme d'autres l'ont fait, mais j'ai ajouté une sous-chaîne pour supprimer les guillemets ajoutés et la barre oblique inverse.
la source
Dans .Net Core 3+ et .Net 5+:
la source
Il y a une bibliothèque Json chez Codeplex
la source
J'ai choisi d'utiliser
System.Web.Script.Serialization.JavaScriptSerializer
.J'ai une petite classe d'assistance statique définie comme suit:
Pour sérialiser tout ce que je viens d'appeler
Serialization.ToJSON(itemToSerialize)
Pour désérialiser je viens d'appeler
Serialization.FromJSON<T>(jsonValueOfTypeT)
la source