2009-08-06 9 views

Odpowiedz

0

Istnieje biblioteka Json w Codeplex

+0

i przykłady: http://james.newtonking.com/projects/json/help/ –

17

Tak, wystarczy dodać następującą funkcję do klasy Utils lub coś:

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

Dlaczego potrzebujesz ucieczki '/'? – drzaus

16

Użyłem następujący kod do ucieczki ciąg wartości dla JSON. Trzeba dodać swoje '"' z wyjściem następującego kodu:

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

To naprawdę uratowało mój dzień. Wielkie dzięki! – casaout

+3

Nie używaj tego kodu w produkcji! Ten JSON ucieka, nie trafia w ważne znaki specjalne. Zobacz: http://stackoverflow.com/a/33799784 – vog

+1

Ten kod nie obejmuje wszystkich specjalnych przypadków. NIE używaj w produkcji. – Envil

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

To po prostu wyjść: X

Spróbuj to zamiast:

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

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

Budynek na the answer by Dejan, co można zrobić, to import System.Web.Helpers .NET Framework assembly, a następnie skorzystać z następujących funkcji:

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

Substring połączenie jest wymagane, ponieważ Encode automatycznie otacza struny cudzysłów.

+0

Wygląda na to, że System.Web.Helpers nie jest dostępny przed .Net 4.0 – SerG

+0

... i nie więcej w Visual Studio 2015 też. – lapo

+2

Jest to część stron internetowych ASP.NET 2.0. Można go dodać za pomocą NuGet. To nie jest część ram. – Murven

16

Dla tych, używając bardzo popularny projekt Json.NET z Newtonsoft zadanie jest trywialne:

using Newtonsoft.Json; 

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

Ten kod drukuje:

"a \\ b"

Oznacza to, że wynikowa wartość ciągu zawiera cudzysłowy, a także ukośnik odwrotny.

+2

Nie mogę odtworzyć tej metody deserializacji kodowanej i unikniętej ścieżki unc. Moja ścieżka '" WatchedPath ":" \\\\ myserver \\ output "' staje się '" \ "\ myserver \\\\ output" ", co jest całkiem niedopuszczalne. – slestak

+3

Powyższa metoda nie służy do deserializacji - rater jest używana, gdy chcesz ręcznie utworzyć tekst JSON i masz łańcuch C# i musisz uzyskać jego odpowiednią reprezentację jako tekst. –

+0

@slestak, myślę, że mam do czynienia z tym samym problemem, który tu pan był. Znalazłeś rozwiązanie? – GP24

29

używam System.Web.HttpUtility.JavaScriptStringEncode

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

Użyłem tego, aby ominąć brakujący 'System.Web.Helpers.Json.Encode' w VS2015, ale potrzebny jest również parametr' (input, true) ', aby uwzględnić również faktyczne cytaty. – lapo

3

Pobiegłem testy prędkości na niektórych z tych odpowiedzi dla długiego łańcucha i krótkiego łańcucha. Clive Paterson's code wygrał przez dobry kawałek, prawdopodobnie dlatego, że inni biorą pod uwagę opcje serializacji. Oto moje wyniki:

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 

I Oto kod testu:

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

Metody oferowane tutaj są wadliwe.
Po co wybierać tak daleko, skoro można po prostu użyć System.Web.HttpUtility.JavaScriptEncode?

Jeśli jesteś na dolnej ramy, można po prostu skopiować obok niego z mono

uprzejmości 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(); 
    } 

To może być zagęszczona do

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