2009-08-06 11 views

Respuesta

0

Hay una biblioteca JSON en Codeplex

+0

y ejemplos: http://james.newtonking.com/projects/json/help/ –

4

También recomendaría el uso de la JSON.NET biblioteca mencionado, pero si tiene que escapar caracteres Unicode (formato por ejemplo \ uXXXX) en la cadena JSON resultante, puede que tenga que hacerlo tú mismo. Eche un vistazo a Converting Unicode strings to escaped ascii string para ver un ejemplo.

17

Sí, sólo tiene que añadir la siguiente función a su clase o algo Utilidades:

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

¿Por qué necesita escapar '/'? – drzaus

16

he utilizado siguiente código para escapar del valor de cadena para JSON. Es necesario añadir su '"' a la salida del siguiente código:

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

Esto realmente me salvó el día. ¡Muchas gracias! – casaout

+3

¡No use este código en producción! Este escape JSON pierde importantes personajes especiales. Ver: http://stackoverflow.com/a/33799784 – vog

+1

Este código no cubre todos los casos especiales. NO usar en producción – Envil

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

Eso sólo da salida: X

Tal vez puedas probar:

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

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

Construyendo en the answer by Dejan, lo que puede hacer es import System.Web.Helpers .NET Framework assembly, a continuación, utilizar la siguiente función:

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

Se requiere que la llamada Substring, ya Encode rodea automáticamente las cadenas con comillas dobles.

+0

Parece que System.Web.Helpers no está disponible antes de .Net 4.0 – SerG

+0

... y tampoco en Visual Studio 2015. – lapo

+2

Esto es parte de ASP.NET Web Pages 2.0. Se puede agregar usando NuGet. No es parte del marco. – Murven

16

Para aquellos que utilizan el proyecto Json.Net muy populares desde Newtonsoft la tarea es trivial:

using Newtonsoft.Json; 

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

Este código imprime:

"un \\ b"

Es decir, el El valor de cadena resultante contiene las comillas, así como la barra invertida escapada.

+2

No puedo reproducir este método para deserializar una ruta de acceso unc codificada y escapada. Mi ruta '" WatchedPath ":" \\\\ miservidor \\ salida "' se convierte en '" \ "\\\\\\\\\\\\ miserver \\\\ output \" "' que es bastante inaceptable. – slestak

+3

El método anterior no es para deserializar, sino que se usa cuando desea crear un texto JSON manualmente y tiene una cadena C# y necesita obtener su representación correcta como texto. –

+0

@slestak, creo que estoy enfrentando el mismo problema que usted estuvo aquí. ¿Encontraste una solución? – GP24

29

utilizo System.Web.HttpUtility.JavaScriptStringEncode

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

Utilicé esto para evitar la falta de 'System.Web.Helpers.Json.Encode' en VS2015, pero necesita el parámetro' (input, true) 'para incluir las comillas reales también. – lapo

3

me corrieron pruebas de velocidad en algunas de estas respuestas para una cadena larga y una cadena corta. El code de Clive Paterson ganó un buen tiempo, presumiblemente porque los otros están teniendo en cuenta las opciones de serialización. Aquí están mis resultados:

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 

y aquí está el código de prueba:

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

Los métodos que aquí se ofrecen son defectuosos.
¿Por qué aventurarse tan lejos cuando podría simplemente usar System.Web.HttpUtility.JavaScriptEncode?

Si estás en un marco inferior, que sólo puede copiar pasado desde mono

Cortesía de la mono-proyecto @ 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(); 
    } 

Esto puede compactarse en

// 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(); 
    } 
} 
Cuestiones relacionadas