当前位置:  开发笔记 > 编程语言 > 正文

用于javascript消费的C#中的Escape报价

如何解决《用于javascript消费的C#中的Escape报价》经验,为你挑选了4个好方法。

我有一个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#(一般的编码)很新,所以如果我的代码中的其他内容看起来很傻,请告诉我.



1> Yauhen.F..:

对于.net 4.0 +有标准 HttpUtility.JavaScriptStringEncode

对于Lone Coder描述的早期西风解决方案来说相当不错


我正在使用Uri.EscapeDataString开发软件,当引号包含在字符串中时会引起问题。更改为HttpUtility.JavaScriptStringEncode是正确的解决方案。他们以不同的方式掩盖角色。EscapeDataString->%25,JavaScriptStringEncode-> \\“ ....更新。最后,我既需要Url.EscapeDataString(HttpUtility.JavaScriptStringEncode(str))来获得一个接受引号(”)的api和百分比字符。也许有更好的方法,但希望此评论对某人有帮助。

2> Bryan Legend..:

这是一个有效而强大的方法,我在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();
}


使用这样的方法对于避免在评估JSON时可能发生的XSS攻击非常重要.

3> Artiom Chila..:

我认为你应该看一下JavaScriptSerializer类.它更稳定,并且可以正确处理任何类型的数据或转义字符等.此外,您的代码看起来会更清晰.

在您的情况下,您的课程可能如下所示:

public static String dt2JSON(DataTable dt) {
    var rows = new List();
    foreach(DataRow row in dt.Rows)
    {
        var rowData = new Dictionary();
        foreach(DataColumn col in dt.Columns)
            rowData[col.ColumnName] = row[col];
        rows.Add(rowData);
    }
    var js = new JavaScriptSerializer();
    return js.Serialize(new { rows = rows });
}


此方法将返回正确序列化的json字符串...例如,像这样:

{"rows":[{"id":1,"name":"hello"},{"id":2,"name":"bye"}]}

玩得开心!:)



4> Guffa..:

要正确转义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();
}

推荐阅读
linjiabin43
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有