我有一个ASP.Net Web处理程序,它以JSON格式返回查询结果
public static String dt2JSON(DataTable dt)
{
String s = "{\"rows\":[";
if (dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
s += "{";
for (int i = 0; i < dr.Table.Columns.Count; i++)
{
s += "\"" + dr.Table.Columns[i].ToString() + "\":\"" + dr[i].ToString() + "\",";
}
s = s.Remove(s.Length - 1, 1);
s += "},";
}
s = s.Remove(s.Length - 1, 1);
}
s += "]}";
return s;
}
Run Code Online (Sandbox Code Playgroud)
问题是有时返回的数据中有引号,我需要javascript-escape这些,以便它可以正确地创建到js对象中.我需要一种在我的数据中找到引号的方法(引号不是每次都有引号)并在它们前面放置一个"/"字符.
示例响应文本(错误):
{"rows":[{"id":"ABC123","length":"5""},
{"id":"DEF456","length":"1.35""},
{"id":"HIJ789","length":"36.25""}]}
Run Code Online (Sandbox Code Playgroud)
我需要逃避"所以我的回答应该是:
{"rows":[{"id":"ABC123","length":"5\""},
{"id":"DEF456","length":"1.35\""},
{"id":"HIJ789","length":"36.25\""}]}
Run Code Online (Sandbox Code Playgroud)
另外,我对C#(一般的编码)很新,所以如果我的代码中的其他内容看起来很傻,请告诉我.
Yau*_*n.F 158
对于.net 4.0 +有标准
HttpUtility.JavaScriptStringEncode
对于Lone Coder描述的早期西风解决方案来说相当不错
Bry*_*end 34
这是一个有效而强大的方法,我在http://www.west-wind.com/weblog/posts/114530.aspx找到
/// <summary>
/// Encodes a string to be represented as a string literal. The format
/// is essentially a JSON string.
///
/// The string returned includes outer quotes
/// Example Output: "Hello \"Rick\"!\r\nRock on"
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string EncodeJsString(string s)
{
StringBuilder sb = new StringBuilder();
sb.Append("\"");
foreach (char c in s)
{
switch (c)
{
case '\"':
sb.Append("\\\"");
break;
case '\\':
sb.Append("\\\\");
break;
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;
default:
int i = (int)c;
if (i < 32 || i > 127)
{
sb.AppendFormat("\\u{0:X04}", i);
}
else
{
sb.Append(c);
}
break;
}
}
sb.Append("\"");
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
Art*_*aru 11
我认为你应该看一下JavaScriptSerializer类.它更稳定,并且可以正确处理任何类型的数据或转义字符等.此外,您的代码看起来会更清晰.
在您的情况下,您的课程可能如下所示:
public static String dt2JSON(DataTable dt) {
var rows = new List<Object>();
foreach(DataRow row in dt.Rows)
{
var rowData = new Dictionary<string, object>();
foreach(DataColumn col in dt.Columns)
rowData[col.ColumnName] = row[col];
rows.Add(rowData);
}
var js = new JavaScriptSerializer();
return js.Serialize(new { rows = rows });
}
Run Code Online (Sandbox Code Playgroud)
此方法将返回正确序列化的json字符串...例如,像这样:
{"rows":[{"id":1,"name":"hello"},{"id":2,"name":"bye"}]}
Run Code Online (Sandbox Code Playgroud)
玩得开心!:)
要正确转义Javascript的字符串文字,首先要转义所有反斜杠字符,然后转义引号(如果将它们用作字符串分隔符,则转义为撇号).
那么,你需要的是:
value.Replace("\\","\\\\").Replace("\"","\\\"")
Run Code Online (Sandbox Code Playgroud)
跳到我身边的另一个原因是你在循环中使用字符串连接.这很糟糕,因为它的扩展性非常差.+ =运算符不会在现有字符串的末尾添加字符(因为字符串是不可变的并且永远不能更改),而是将字符串和添加的字符复制到新字符串.每次复制越来越多的数据时,eEvery附加行大约会使方法的执行时间加倍.使用StringBuilder来构建字符串.
使用该ColumnName属性获取列的名称而不是ToString方法.如果设置ToString了该Expression属性值,则该方法返回该属性值,仅当未设置该属性值时才返回该ColumnName属性.
public static String dt2JSON(DataTable dt) {
StringBuilder s = new StringBuilder("{\"rows\":[");
bool firstLine = true;
foreach (DataRow dr in dt.Rows) {
if (firstLine) {
firstLine = false;
} else {
s.Append(',');
}
s.Append('{');
for (int i = 0; i < dr.Table.Columns.Count; i++) {
if (i > 0) {
s.Append(',');
}
string name = dt.Columns[i].ColumnName;
string value = dr[i].ToString();
s.Append('"')
.Append(name.Replace("\\","\\\\").Replace("\"","\\\""))
.Append("\":\"")
.Append(value.Replace("\\","\\\\").Replace("\"","\\\""))
.Append('"');
}
s.Append("}");
}
s.Append("]}");
return s.ToString();
}
Run Code Online (Sandbox Code Playgroud)
你为什么不这样做:
string correctResponseText = wrongResponseText.Replace("\"", "\\\"");
Run Code Online (Sandbox Code Playgroud)