Подтвердить что ты не робот

Escape Quote в С# для потребления javascript

У меня есть веб-обработчик ASP.Net, который возвращает результаты запроса в формате 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\""}]}

Кроме того, я довольно новичок в С# (вообще, кодирование), поэтому, если что-то еще в моем коде выглядит глупо, дайте мне знать.

4b9b3361

Ответ 1

Для .net 4.0 + есть стандартный HttpUtility.JavaScriptStringEncode

Для более раннего западного ветра, описанного Lone Coder, довольно приятно

Ответ 2

Вот эффективный и надежный метод, который я нашел в 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();
}

Ответ 3

Я думаю, вам стоит взглянуть на класс 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 });
}

Этот метод вернет правильно сериализованную строку json... Например, sth, как это:

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

Удачи!:)

Ответ 4

Чтобы правильно избежать строкового литерала для 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();
}

Ответ 5

Почему бы вам просто не сделать это:

string correctResponseText = wrongResponseText.Replace("\"", "\\\"");

Ответ 6

string.Replace(<mystring>, @"\"", @"\\"");

Ответ 7

Работает, когда мне нужно отправить строку из тега С# в html.

<buton onlick="alert('<< here >>')" />

HttpUtility.HtmlEncode

Ответ 8

Ну, для начала вам не нужны кавычки вокруг клавиш.

{rows:[,]} is valid.

and you could dt.Table.Columns[i].ToString().Replace("\","")

Но если вы хотите сохранить двойные кавычки, одиночная кавычка работает так же, как и двойные кавычки в JS

В противном случае вы могли бы сделать

String.Format("{name: \"{0}\"}",Columns[i].ToString().Replace("\",""))