Forma adecuada de escapar caracteres de RegisterStartupScript

ScriptManager.RegisterStartupScript(page, 
    page.GetType(),
    "KEY",
    "updateDockTitle('" + ClientID + "', '" + string.Format(format, ChartName, "No Data To Display") + "');".Replace("-", "\\-"),
    true);

ChartName tiene la capacidad de contener caracteres especiales (por ejemplo, el gráfico de alguien). Si se permite como está, esto causa un error, el código golpea el ' cuando no lo esperaba.

¿Cuál es la forma correcta de manejar este escenario? ¿Necesito conocer todos los personajes que podrían causar problemas y reemplazarlos con versiones escapadas?

preguntado el 16 de mayo de 11 a las 16:05

2 Respuestas

Encontré esta solución integral a mano:

private static readonly Regex scriptTagRegex = new Regex(
    "script", RegexOptions.IgnoreCase | RegexOptions.Multiline);

/// <summary>
///     Processes the provided string, creating a quoted JavaScript string literal.
/// </summary>
/// <param name="str">The string to process</param>
/// <returns>A string containing a quoted JavaScript string literal</returns>
public static string JavaScriptStringLiteral(string str)
{
    var sb = new StringBuilder();
    sb.Append("\"");
    foreach (char c in str)
    {
        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("\"");

    // If a Javascript tag contains "</script>", then it terminates a
    // script block.  Start by replacing each 's'/'S' with an escape
    // sequence so it doesn't trigger this.
    return scriptTagRegex.Replace(
        sb.ToString(),
        m => (m.Value[0] == 's' ? "\\u0073" : "\\u0053") + m.Value.Substring(1));
}

Debería reemplazar todos los caracteres JS no válidos y también asegurarse de que no haya roturas si su script está en línea (lo que sería en su caso). Tenga en cuenta que ya genera las comillas para el literal de cadena, así que téngalo en cuenta si decide usarlo.

contestado el 16 de mayo de 11 a las 20:05

El punto es el escape del 'para su cadena de Javascript. Necesitas escapar de ese carácter con un \, lo que lo convierte en \'

Entonces tu código se convierte

ScriptManager.RegisterStartupScript(page, page.GetType()
       , "KEY", "updateDockTitle('" + ClientID + "', '" 
                                    + string.Format(format, ChartName.Replace("'", "\'")
                                               , "No Data To Display") 
                                    + "');".Replace("-", "\\-"), true);

editar

Creo que tu código es falso, la parte que dice

');".Replace("-", "\\-")

es inútil. Cambiaría tu código a

ScriptManager.RegisterStartupScript(page, page.GetType()
       , "KEY", string.Format("updateDockTitle('{0}', '{1}');"
                             , ClientID 
                             , string.Format(format
                                             , ChartName.Replace("'", "\'").Replace("-", "\\-")
                                             , "No Data To Display")
                             )
       , true);

Pero entonces la pregunta es, ¿por qué necesitarías .Replace("-", "\\-") ?

contestado el 16 de mayo de 11 a las 20:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.