如何逃避JSONstring?
有没有任何类/function可用于简单的JSON转义? 我宁愿不必写我自己的。
您可能需要查看MSDN上的.Net中的JSON简介以及JayRock JSON中的JsonConvert类。
作为一个方面说明,我们使用Jayrock所有我们的产品Json的目的。
基于Dejan的答案 ,你可以做的是导入System.Web.Helpers
.NET Framework程序集 ,然后使用以下函数:
static string EscapeForJson(string s) { string quoted = System.Web.Helpers.Json.Encode(s); return quoted.Substring(1, quoted.Length - 2); }
Substring
调用是必需的,因为Encode
自动将string用双引号括起来。
我使用System.Web.HttpUtility.JavaScriptStringEncode
string quoted = HttpUtility.JavaScriptStringEncode(input);
是的,只需将以下函数添加到您的Utils类或其他东西:
public static string cleanForJSON(string s) { if (s == null || s.Length == 0) { return ""; } char c = '\0'; int i; int len = s.Length; StringBuilder sb = new StringBuilder(len + 4); String t; for (i = 0; i < len; i += 1) { c = s[i]; switch (c) { case '\\': case '"': sb.Append('\\'); sb.Append(c); break; case '/': sb.Append('\\'); sb.Append(c); break; case '\b': sb.Append("\\b"); break; case '\t': sb.Append("\\t"); break; case '\n': sb.Append("\\n"); break; case '\f': sb.Append("\\f"); break; case '\r': sb.Append("\\r"); break; default: if (c < ' ') { t = "000" + String.Format("X", c); sb.Append("\\u" + t.Substring(t.Length - 4)); } else { sb.Append(c); } break; } } return sb.ToString(); }
我已经使用下面的代码来为json转义string值。 您需要将以下代码的输出添加到“”中:
public static string EscapeStringValue(string value) { const char BACK_SLASH = '\\'; const char SLASH = '/'; const char DBL_QUOTE = '"'; var output = new StringBuilder(value.Length); foreach (char c in value) { switch (c) { case SLASH: output.AppendFormat("{0}{1}", BACK_SLASH, SLASH); break; case BACK_SLASH: output.AppendFormat("{0}{0}", BACK_SLASH); break; case DBL_QUOTE: output.AppendFormat("{0}{1}",BACK_SLASH,DBL_QUOTE); break; default: output.Append(c); break; } } return output.ToString(); }
对于那些使用Newtonsoft非常stream行的Json.Net项目来说,这个任务是微不足道的:
using Newtonsoft.Json; .... var s = JsonConvert.ToString("a\\b"); Console.WriteLine(s); ....
此代码打印:
“一个\\ b” 的
也就是说,结果string值包含引号以及转义的反斜杠。
我还build议使用提到的JSON.NET库,但是如果您必须在生成的JSONstring中转义unicode字符(例如\ uXXXX格式),您可能必须自己做。 看一看转换Unicodestring转义asciistring为例。
什么System.Web.Helpers.Json.Encode(…)(请参阅http://msdn.microsoft.com/en-us/library/system.web.helpers.json.encode(v=vs.111); .aspx )?
String.Format("X", c);
那只是输出:X
试试这个:
string t = ((int)c).ToString("X"); sb.Append("\\u" + t.PadLeft(4, '0'));
我对一些长string和短string的答案进行了速度testing。 克莱夫·帕特森的代码赢了很多,大概是因为其他人正在考虑序列化选项。 这是我的结果:
Apple Banana System.Web.HttpUtility.JavaScriptStringEncode: 140ms System.Web.Helpers.Json.Encode: 326ms Newtonsoft.Json.JsonConvert.ToString: 230ms Clive Paterson: 108ms \\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 System.Web.HttpUtility.JavaScriptStringEncode: 2849ms System.Web.Helpers.Json.Encode: 3300ms Newtonsoft.Json.JsonConvert.ToString: 2827ms Clive Paterson: 1173ms
这里是testing代码:
public static void Main(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 in new[] { testStr1, testStr2 }) { var results = new Dictionary<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(); }
这里提供的方法是错误的。
为什么冒险那么远,当你可以使用System.Web.HttpUtility.JavaScriptEncode?
如果你在一个较低的框架,你可以从单声道复制过去
感谢mono-project @ https://github.com/mono/mono/blob/master/mcs/class/System.Web/System.Web/HttpUtility.cs
public static string JavaScriptStringEncode(string value, 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 = new System.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); else switch ((int)c) { case 8: sb.Append("\\b"); break; case 9: sb.Append("\\t"); break; case 10: sb.Append("\\n"); break; case 12: sb.Append("\\f"); break; case 13: sb.Append("\\r"); break; case 34: sb.Append("\\\""); break; case 92: sb.Append("\\\\"); break; default: sb.Append(c); break; } } if (addDoubleQuotes) sb.Append('"'); return sb.ToString(); }
这可以压缩成
// https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs public class SimpleJSON { private static bool NeedEscape(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] == '<'); } public static string EscapeString(string src) { System.Text.StringBuilder sb = new System.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(); } }
Codeplex有一个Json库