用于javascript消费的C#转义引号
我有一个ASP.NETWeb处理程序,它以JSON格式返回查询结果用于javascript消费的C#转义引号,c#,escaping,C#,Escaping,我有一个ASP.NETWeb处理程序,它以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 <
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;
}
我需要避开“所以我的回答应该是:
{"rows":[{"id":"ABC123","length":"5\""},
{"id":"DEF456","length":"1.35\""},
{"id":"HIJ789","length":"36.25\""}]}
另外,我对C#(一般来说真的是编码)非常陌生,所以如果我的代码中有其他东西看起来很愚蠢,请告诉我。为什么不这样做:
string correctResponseText = wrongResponseText.Replace("\"", "\\\"");
string.Replace(,@“\”,@“\”);
好吧,对于初学者来说,键周围不需要引号
{rows:[,]} is valid.
and you could dt.Table.Columns[i].ToString().Replace("\","")
但是如果您想保留双引号,单引号的工作原理与JS中双引号的工作原理相同
否则你可以
String.Format("{name: \"{0}\"}",Columns[i].ToString().Replace("\",""))
要正确转义Javascript的字符串文字,首先要转义所有反斜杠字符,然后转义引号(或撇号,如果将它们用作字符串分隔符) 因此,您需要的是:
value.Replace("\\","\\\\").Replace("\"","\\\"")
我还想知道的是,您正在循环中使用字符串连接。这很糟糕,因为它的伸缩性非常差。+=运算符不会在现有字符串的末尾添加字符(因为字符串是不可变的,永远无法更改),而是将字符串和添加的字符复制到新字符串中。当您每次复制越来越多的数据时,每增加一行都会使方法的执行时间大约翻倍。请改用StringBuilder来生成字符串
使用ColumnName
属性来获取列的名称,而不是ToString
方法。如果设置了ToString
方法,则返回表达式
属性值,只有未设置时,才返回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();
}
公共静态字符串dt2JSON(数据表dt){
StringBuilder s=新的StringBuilder(“{\”行\“:[”);
bool firstLine=true;
foreach(数据行dr在dt.行中){
如果(第一线){
firstLine=false;
}否则{
s、 附加(',');
}
s、 附加('{');
for(int i=0;i0){
s、 附加(',');
}
string name=dt.Columns[i].ColumnName;
字符串值=dr[i].ToString();
s、 追加(“”)
.Append(name.Replace(“\\”,“\\\”)。Replace(“\\”,“\\\”))
.Append(“\”:\”)
.Append(value.Replace(“\\”,“\\\”)。Replace(“\\”,“\\\”))
.Append(“”);
}
s、 附加(“}”);
}
s、 附加(“]}”);
返回s.ToString();
}
这是我在
//
///对要表示为字符串文字的字符串进行编码
///本质上是一个JSON字符串。
///
///返回的字符串包含外部引号
///示例输出:“你好\“瑞克\”\r\n锁定“打开”
///
///
///
公共静态字符串EncodeJsString(字符串s)
{
StringBuilder sb=新的StringBuilder();
某人加上“\”;
foreach(字符c在s中)
{
开关(c)
{
案例“\”:
某人附加(“\\\”);
打破
案例“\\”:
某人加上“\\\”;
打破
案例'\b':
sb.附加(\\b”);
打破
案例'\f':
某人附加(\\f);
打破
案例“\n”:
某人附加(\\n);
打破
案例'\r':
某人附加(\\r);
打破
案例'\t':
某人附加(\\t);
打破
违约:
int i=(int)c;
如果(i<32 | i>127)
{
sb.AppendFormat(“\\u{0:X04}”,i);
}
其他的
{
sb.附加(c);
}
打破
}
}
某人加上“\”;
使某人返回字符串();
}
我认为您应该看看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 });
}
{"rows":[{"id":1,"name":"hello"},{"id":2,"name":"bye"}]}
玩得开心!:)对于.NET4.0+来说,有一个标准
HttpUtility.JavaScriptStringEncode
对于早期的west wind,由Lone Coder描述的解决方案非常好在我需要将字符串从C#发送到html标记时起作用
<buton onlick="alert('<< here >>')" />
HttpUtility.HtmlEncode
HttpUtility.HtmlEncode
以下是@Bryan Legend对Linq的回答的重做:
public static string EncodeJavaScriptString(string s)
=> string.Concat(s.Select(c => {
switch (c)
{
case '\"': return "\\\"";
case '\\': return "\\\\";
case '\b': return "\\b";
case '\f': return "\\f";
case '\n': return "\\n";
case '\r': return "\\r";
case '\t': return "\\t";
default: return (c < 32 || c > 127) && !char.IsLetterOrDigit(c) ? $"\\u{(int)c:X04}" : c.ToString();
}}));
公共静态字符串编码JavaScriptString(字符串s)
=>string.Concat(s.Select(c=>{
开关(c)
{
大小写“\”:返回“\ \”;
大小写“\\”:返回“\\\”;
大小写“\b”:返回“\\b”;
大小写“\f”:返回“\\f”;
大小写“\n”:返回“\\n”;
大小写“\r”:返回“\\r”;
大小写“\t”:返回“\\t”;
默认值:返回(c<32 | | c>127)和&!char.isleterordigit(c)?$“\\u{(int)c:X04}”:c.ToString();
}}));
更改日志:
- 删除双引号包装,因为我在js中这样做
- 使用表达式体
- 使用清洁开关
- 使用Linq
- 添加字母检查以允许
é
“
,如果字符串被写入页面脚本,则会关闭字符串和脚本标记,后跟注入器想要执行的任何操作。@MonsterMMORPG:您不解码它,而是解析它。浦
{"rows":[{"id":1,"name":"hello"},{"id":2,"name":"bye"}]}
<buton onlick="alert('<< here >>')" />
HttpUtility.HtmlEncode
public static string EncodeJavaScriptString(string s)
=> string.Concat(s.Select(c => {
switch (c)
{
case '\"': return "\\\"";
case '\\': return "\\\\";
case '\b': return "\\b";
case '\f': return "\\f";
case '\n': return "\\n";
case '\r': return "\\r";
case '\t': return "\\t";
default: return (c < 32 || c > 127) && !char.IsLetterOrDigit(c) ? $"\\u{(int)c:X04}" : c.ToString();
}}));