Có bất kỳ lớp / chức năng nào có sẵn để sử dụng để dễ dàng thoát JSON không? Tôi không muốn phải viết của riêng tôi.
Có bất kỳ lớp / chức năng nào có sẵn để sử dụng để dễ dàng thoát JSON không? Tôi không muốn phải viết của riêng tôi.
Câu trả lời:
tôi sử dụng System.Web.HttpUtility.JavaScriptStringEncode
string quoted = HttpUtility.JavaScriptStringEncode(input);
System.Web.Helpers.Json.Encode
trong VS2015, nhưng nó cũng cần (input, true)
tham số để bao gồm các trích dẫn thực tế.
Đối với những người sử dụng dự án Json.Net rất phổ biến từ Newtonsoft, nhiệm vụ là rất nhỏ:
using Newtonsoft.Json;
....
var s = JsonConvert.ToString(@"a\b");
Console.WriteLine(s);
....
Mã này in:
"a \\ b"
Nghĩa là, giá trị chuỗi kết quả chứa các dấu ngoặc kép cũng như dấu gạch chéo ngược thoát.
"WatchedPath": "\\\\myserver\\output"
trở thành "\"\\\\\\\\myserver\\\\output\""
điều không thể chấp nhận được.
Dựa trên câu trả lời của Dejan , những gì bạn có thể làm là nhập System.Web.Helpers
.NET Framework lắp ráp , sau đó sử dụng chức năng sau:
static string EscapeForJson(string s) {
string quoted = System.Web.Helpers.Json.Encode(s);
return quoted.Substring(1, quoted.Length - 2);
}
Cuộc Substring
gọi là bắt buộc, vì Encode
tự động bao quanh chuỗi bằng dấu ngoặc kép.
Đúng, chỉ cần thêm hàm sau vào lớp Utils của bạn hoặc thứ gì đó:
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);
Tôi đã sử dụng mã sau để thoát giá trị chuỗi cho json. Bạn cần thêm '"' của mình vào đầu ra của mã sau:
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();
}
Các phương pháp được cung cấp ở đây bị lỗi.
Tại sao phải mạo hiểm xa như vậy khi bạn chỉ có thể sử dụng System.Web.HttpUtility.JavaScriptEncode?
Nếu bạn đang ở trong một khuôn khổ thấp hơn, bạn chỉ có thể sao chép và dán nó từ mono
Được phép của đơn dự án @ 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();
}
Điều này có thể được nén thành
// 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();
}
}
Tôi cũng khuyên bạn nên sử dụng thư viện JSON.NET đã đề cập, nhưng nếu bạn phải thoát các ký tự unicode (ví dụ: định dạng \ uXXXX) trong chuỗi JSON kết quả, bạn có thể phải tự thực hiện. Hãy xem Chuyển đổi chuỗi Unicode thành chuỗi ascii thoát để làm ví dụ.
Tôi đã chạy các bài kiểm tra tốc độ trên một số câu trả lời này cho một chuỗi dài và một chuỗi ngắn. Mã của Clive Paterson đã thắng được một chút, có lẽ là do những người khác đang tính đến các tùy chọn tuần tự hóa. Đây là kết quả của tôi:
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
Và đây là mã kiểm tra:
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();
}
Còn System.Web.Helpers.Json.Encode (...) (xem http://msdn.microsoft.com/en-us/library/system.web.helpers.json.encode(v=vs.111) .aspx )?
String.Format("X", c);
Điều đó chỉ xuất ra: X
Hãy thử cái này thay thế:
string t = ((int)c).ToString("X");
sb.Append("\\u" + t.PadLeft(4, '0'));
Tôi đẹp một chữ lót, đã sử dụng JsonConvert như những người khác nhưng đã thêm chuỗi con để loại bỏ các dấu ngoặc kép và dấu gạch chéo ngược đã thêm.
var escapedJsonString = JsonConvert.ToString(JsonString).Substring(1, JsonString.Length - 2);
Trong .Net Core 3+ và .Net 5+:
string escapedJsonString = JsonEncodedText.Encode(jsonString);
Có một thư viện Json tại Codeplex
Tôi đã chọn để sử dụng System.Web.Script.Serialization.JavaScriptSerializer
.
Tôi có một lớp trợ giúp tĩnh nhỏ được định nghĩa như sau:
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);
}
}
Để tuần tự hóa bất cứ thứ gì tôi chỉ cần gọi Serialization.ToJSON(itemToSerialize)
Để deserialize, tôi chỉ cần gọi Serialization.FromJSON<T>(jsonValueOfTypeT)