@MartinLottering Dziękuję !!! Szukałem sposobu, aby uzyskać JSON do sformatowanego ciągu. Żadna z poniższych odpowiedzi nie zadziałała, ale zadziałało.
Użyłem tego, aby uniknąć brakujących danych System.Web.Helpers.Json.Encodew VS2015, ale potrzebuje on również (input, true)parametru, aby uwzględnić również rzeczywiste cytaty.
Lapo
To było dla mnie brakujące ogniwo
Jawid Hassim
50
Dla osób korzystających z bardzo popularnego projektu Json.Net firmy Newtonsoft zadanie jest banalne:
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 odwrotny ukośnik uciekający.
Nie mogę odtworzyć tej metody deserializacji zakodowanej i uciekającej ścieżki UNC. Moja ścieżka "WatchedPath": "\\\\myserver\\output"staje "\"\\\\\\\\myserver\\\\output\""się czymś nie do przyjęcia.
sen
3
Powyższa metoda nie służy do deserializacji - rater jest używana, gdy chcesz ręcznie utworzyć tekst JSON i masz ciąg C # i musisz uzyskać jego odpowiednią reprezentację jako tekst.
Dror Harari
@slestak, myślę, że mam ten sam problem, co ty tutaj. Znalazłeś rozwiązanie?
GP24
@ GP24 IIRC, nie zrobiłem. Przepraszam, nie mam więcej informacji.
slestak
Nie ma problemu, dziękuję za odpowiedź. Zrobiłem to, jeśli ci to pomoże: yourAnnoyingDoubleEncodedString.Replace ("\\\\", "\\"). Zastąp ("\\\", "\" ");
Wiem, że to stara odpowiedź i cieszę się, że została podana, ponieważ nie chciałem polegać na żadnych bibliotekach zewnętrznych, ale zauważyłem, że domyślna wielkość znaku kontrolnego zawsze zwraca „\\ u000X”. Uważam, że najpierw musisz rzucić char na int. Rozważ zastąpienie gostring t = "000" + ((int)c).ToString("X");
Przeprowadziłem testy szybkości dla niektórych z tych odpowiedzi dla długiego i krótkiego ciągu. Kod Clive'a Patersona wygrał sporo, prawdopodobnie dlatego, że inni biorą pod uwagę opcje serializacji. Oto moje wyniki:
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 = 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();
}
Odpowiedzi:
używam
System.Web.HttpUtility.JavaScriptStringEncode
string quoted = HttpUtility.JavaScriptStringEncode(input);
źródło
System.Web.Helpers.Json.Encode
w VS2015, ale potrzebuje on również(input, true)
parametru, aby uwzględnić również rzeczywiste cytaty.Dla osób korzystających z bardzo popularnego projektu Json.Net firmy Newtonsoft zadanie jest banalne:
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 odwrotny ukośnik uciekający.
źródło
"WatchedPath": "\\\\myserver\\output"
staje"\"\\\\\\\\myserver\\\\output\""
się czymś nie do przyjęcia.Opierając się na odpowiedzi Dejana , możesz zaimportować
System.Web.Helpers
zestaw .NET Framework , a następnie użyć następującej 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 konieczne, ponieważEncode
automatycznie otacza struny cudzysłów.źródło
Tak, po prostu dodaj następującą funkcję do swojej klasy Utils lub coś takiego:
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(); }
źródło
/
?string t = "000" + ((int)c).ToString("X");
t = "000" + String.Format("{0:X}",(int) c);
"\\u" + ((int)c).ToString("X4")
(chociaż myślę, że dwa Appends byłyby jeszcze lepsze)Użyłem następującego kodu, aby zmienić wartość ciągu dla json. Musisz dodać swój „” ”do wyniku 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(); }
źródło
Oferowane tutaj metody są wadliwe.
Po co zapuszczać się tak daleko, skoro można po prostu użyć System.Web.HttpUtility.JavaScriptEncode?
Jeśli korzystasz z niższej platformy, możesz po prostu skopiować i wkleić ją z mono
Dzięki 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(); }
Można to zagęścić w
// 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(); } }
źródło
Poleciłbym również użycie wspomnianej biblioteki JSON.NET , ale jeśli musisz uciec ze znaków Unicode (np. Format \ uXXXX) w wynikowym ciągu JSON, być może będziesz musiał to zrobić samodzielnie. Spójrz na przykład Konwertowanie ciągów Unicode na ciąg znaków ascii ze znakami ucieczki .
źródło
Przeprowadziłem testy szybkości dla niektórych z tych odpowiedzi dla długiego i krótkiego ciągu. Kod Clive'a Patersona wygrał sporo, 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
A oto kod testowy:
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(); }
źródło
A co z System.Web.Helpers.Json.Encode (...) (patrz http://msdn.microsoft.com/en-us/library/system.web.helpers.json.encode(v=vs.111) .aspx )?
źródło
W .Net Core 3+ i .Net 5+:
string escapedJsonString = JsonEncodedText.Encode(jsonString);
źródło
String.Format("X", c);
To po prostu wyprowadza: X
Spróbuj tego zamiast tego:
string t = ((int)c).ToString("X"); sb.Append("\\u" + t.PadLeft(4, '0'));
źródło
I ładna jedna linijka, użyłem JsonConvert jak inni, ale dodałem podciąg, aby usunąć dodane cudzysłowy i ukośnik odwrotny.
var escapedJsonString = JsonConvert.ToString(JsonString).Substring(1, JsonString.Length - 2);
źródło
W Codeplex jest biblioteka Json
źródło
Zdecydowałem się użyć
System.Web.Script.Serialization.JavaScriptSerializer
.Mam małą statyczną klasę pomocniczą zdefiniowaną w następujący sposób:
internal static partial class Serialization { static JavaScriptSerializer serializer; static Serialization() { serializer = new JavaScriptSerializer(); serializer.MaxJsonLength = Int32.MaxValue; } public static string ToJSON<T>(T obj) { return serializer.Serialize(obj); } public static T FromJSON<T>(string data) { if (Common.IsEmpty(data)) return default(T); else return serializer.Deserialize<T>(data); } }
Aby serializować wszystko, do czego właśnie dzwonię
Serialization.ToJSON(itemToSerialize)
Po prostu dzwonię do deserializacji
Serialization.FromJSON<T>(jsonValueOfTypeT)
źródło