Apakah ada kelas / fungsi yang tersedia untuk digunakan agar JSON mudah melarikan diri? Saya lebih suka tidak harus menulis sendiri.
Apakah ada kelas / fungsi yang tersedia untuk digunakan agar JSON mudah melarikan diri? Saya lebih suka tidak harus menulis sendiri.
Jawaban:
saya menggunakan System.Web.HttpUtility.JavaScriptStringEncode
string quoted = HttpUtility.JavaScriptStringEncode(input);
System.Web.Helpers.Json.Encode
di VS2015, tetapi perlu (input, true)
parameter untuk menyertakan kutipan aktual juga.
Bagi mereka yang menggunakan proyek Json.Net yang sangat populer dari Newtonsoft, tugasnya sepele:
using Newtonsoft.Json;
....
var s = JsonConvert.ToString(@"a\b");
Console.WriteLine(s);
....
Kode ini mencetak:
"a \\ b"
Artinya, nilai string yang dihasilkan berisi tanda kutip serta garis miring terbalik yang lolos.
"WatchedPath": "\\\\myserver\\output"
menjadi "\"\\\\\\\\myserver\\\\output\""
yang sangat tidak bisa diterima.
Membangun jawaban oleh Dejan , apa yang dapat Anda lakukan adalah mengimpor System.Web.Helpers
rakitan .NET Framework , kemudian menggunakan fungsi berikut:
static string EscapeForJson(string s) {
string quoted = System.Web.Helpers.Json.Encode(s);
return quoted.Substring(1, quoted.Length - 2);
}
The Substring
panggilan diperlukan, karena Encode
secara otomatis mengelilingi string dengan tanda kutip ganda.
Ya, cukup tambahkan fungsi berikut ke kelas Utils Anda atau sesuatu:
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();
}
/
?
string t = "000" + ((int)c).ToString("X");
t = "000" + String.Format("{0:X}",(int) c);
"\\u" + ((int)c).ToString("X4")
(Meskipun saya pikir dua Appends akan lebih baik)
Saya telah menggunakan kode berikut untuk menghindari nilai string untuk json. Anda perlu menambahkan '"' Anda ke keluaran dari kode berikut:
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();
}
Metode yang ditawarkan di sini salah.
Mengapa menjelajah sejauh itu ketika Anda bisa menggunakan System.Web.HttpUtility.JavaScriptEncode?
Jika Anda menggunakan kerangka kerja yang lebih rendah, Anda cukup menyalin dan menempelkannya dari mono
Atas kebaikan 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();
}
Ini bisa dipadatkan menjadi
// 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();
}
}
Saya juga merekomendasikan penggunaan pustaka JSON.NET yang disebutkan, tetapi jika Anda harus melepaskan karakter unicode (misalnya \ uXXXX format) dalam string JSON yang dihasilkan, Anda mungkin harus melakukannya sendiri. Lihat Mengonversi string Unicode menjadi string ascii yang di-escape sebagai contoh.
Saya menjalankan tes kecepatan pada beberapa jawaban ini untuk string panjang dan string pendek. Kode Clive Paterson menang sedikit, mungkin karena yang lain mempertimbangkan opsi serialisasi. Ini hasil saya:
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
Dan inilah kode tesnya:
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();
}
Bagaimana dengan System.Web.Helpers.Json.Encode (...) (lihat http://msdn.microsoft.com/en-us/library/system.web.helpers.json.encode(v=vs.111) .aspx )?
Di .Net Core 3+ dan .Net 5+:
string escapedJsonString = JsonEncodedText.Encode(jsonString);
String.Format("X", c);
Itu hanya menghasilkan: X
Coba ini sebagai gantinya:
string t = ((int)c).ToString("X");
sb.Append("\\u" + t.PadLeft(4, '0'));
Saya bagus satu baris, menggunakan JsonConvert seperti yang dimiliki orang lain tetapi menambahkan substring untuk menghapus tanda kutip dan garis miring terbalik yang ditambahkan.
var escapedJsonString = JsonConvert.ToString(JsonString).Substring(1, JsonString.Length - 2);
Ada perpustakaan Json di Codeplex
Saya memilih untuk menggunakan System.Web.Script.Serialization.JavaScriptSerializer
.
Saya memiliki kelas pembantu statis kecil yang didefinisikan sebagai berikut:
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);
}
}
Untuk membuat serialisasi apa pun yang saya sebut saja Serialization.ToJSON(itemToSerialize)
Untuk menghilangkan rasa, saya hanya menelepon Serialization.FromJSON<T>(jsonValueOfTypeT)