2009-08-06 45 views

回答

0

有在Codeplex

+0

和示例:http://james.newtonking.com/projects/json/help/ – 2009-08-06 23:44:02

17

没错,只是添加的功能,以您的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(); 
    } 
+1

为什么你需要转义'/'? – drzaus 2016-04-21 15:11:25

16

我用下面的代码来逃避JSON字符串值。 您需要添加“'下面的代码的输出:

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(); 
} 
+1

这确实节省了我的一天。非常感谢! – casaout 2013-10-31 14:44:15

+3

请勿在生产中使用此代码!这个JSON转义忽略了重要的特殊字符。请参阅:http://stackoverflow.com/a/33799784 – vog 2015-11-19 11:49:21

+1

此代码不涵盖所有特殊情况。不要在生产中使用。 – Envil 2016-09-08 04:49:51

2
String.Format("X", c); 

这只是输出:X

试试这个:

string t = ((int)c).ToString("X"); 

sb.Append("\\u" + t.PadLeft(4, '0')); 
33

建立于the answer by Dejan,你能做的就是import System.Web.Helpers .NET Framework assembly,然后使用以下功能:

static string EscapeForJson(string s) { 
    string quoted = System.Web.Helpers.Json.Encode(s); 
    return quoted.Substring(1, quoted.Length - 2); 
} 

Substring调用是必需的,因为Encode自动包围双引号的字符串。

+0

看起来System.Web.Helpers在.NET 4.0 – SerG 2015-06-09 14:08:34

+0

之前是不可用的,在Visual Studio 2015中也没有更多。 – lapo 2016-06-22 13:45:27

+2

这是ASP.NET Web Pages 2.0的一部分。它可以使用NuGet添加。它不是框架的一部分。 – Murven 2016-12-24 17:37:45

16

对于使用非常流行的Json.Net项目从Newtonsoft任务的是平凡:

using Newtonsoft.Json; 

.... 
var s = JsonConvert.ToString("a\\b"); 
Console.WriteLine(s); 
.... 

此代码打印:

“一\\ B”

也就是说,结果字符串值包含引号以及转义反斜杠。

+2

我无法重现这种反编码和转义的unc路径的方法。我的路径'“WatchedPath”:“\\\\ myserver \\ output”'变成'“\”\\\\\\\ myserver \\\\ output \“”'这是非常不可接受的。 – slestak 2014-12-29 14:36:47

+3

上面的方法不适用于反序列化 - 当您想手动创建JSON文本并使用C#字符串并需要将其正确表示为文本时,使用该方法进行反序列化。 – 2014-12-30 22:50:52

+0

@slestak,我想我正面临同样的问题,你在这里。你找到解决方案吗? – GP24 2016-02-11 11:50:07

29

我用System.Web.HttpUtility.JavaScriptStringEncode

string quoted = HttpUtility.JavaScriptStringEncode(input); 
+2

我用这个来避免在VS2015中丢失'System.Web.Helpers.Json.Encode',但它需要'(input,true)'参数来包含实际的引号。 – lapo 2016-06-22 14:37:01

3

我跑了一些答案的长字符串和短绳的速度测试。 Clive Paterson的code赢得了好评,大概是因为其他人正在考虑序列化选项。下面是我的结果:

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 

,这里是测试代码:

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

这里提供的方法是错误的。
为什么冒险那么远,只要使用System.Web.HttpUtility.JavaScriptEncode?

如果你是在一个较低的框架,你可以复制过去,从单声道单项目的

礼貌@ 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(); 
    } 
}