我有一个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; }
问题是有时返回的数据中有引号,我需要javascript-escape这些,以便它可以正确地创建到js对象中.我需要一种在我的数据中找到引号的方法(引号不是每次都有引号)并在它们前面放置一个"/"字符.
示例响应文本(错误):
{"rows":[{"id":"ABC123","length":"5""}, {"id":"DEF456","length":"1.35""}, {"id":"HIJ789","length":"36.25""}]}
我需要逃避"所以我的回答应该是:
{"rows":[{"id":"ABC123","length":"5\""}, {"id":"DEF456","length":"1.35\""}, {"id":"HIJ789","length":"36.25\""}]}
另外,我对C#(一般的编码)很新,所以如果我的代码中的其他内容看起来很傻,请告诉我.
对于.net 4.0 +有标准
HttpUtility.JavaScriptStringEncode
对于Lone Coder描述的早期西风解决方案来说相当不错
这是一个有效而强大的方法,我在http://www.west-wind.com/weblog/posts/114530.aspx找到
////// 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" /// /// ///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(); }
我认为你应该看一下JavaScriptSerializer类.它更稳定,并且可以正确处理任何类型的数据或转义字符等.此外,您的代码看起来会更清晰.
在您的情况下,您的课程可能如下所示:
public static String dt2JSON(DataTable dt) { var rows = new List
此方法将返回正确序列化的json字符串...例如,像这样:
{"rows":[{"id":1,"name":"hello"},{"id":2,"name":"bye"}]}
玩得开心!:)
要正确转义Javascript的字符串文字,首先要转义所有反斜杠字符,然后转义引号(如果将它们用作字符串分隔符,则转义为撇号).
那么,你需要的是:
value.Replace("\\","\\\\").Replace("\"","\\\"")
跳到我身边的另一个原因是你在循环中使用字符串连接.这很糟糕,因为它的扩展性非常差.+ =运算符不会在现有字符串的末尾添加字符(因为字符串是不可变的并且永远不能更改),而是将字符串和添加的字符复制到新字符串.每次复制越来越多的数据时,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(); }