2010-05-27 13 views
68

Sto cercando di passare l'output di un'eccezione di SQL Server al client utilizzando il metodo RegisterStartUpScript di MS ScriptManager in .NET 3.5. Funziona bene per alcuni errori ma quando l'eccezione contiene virgolette singole l'avviso fallisce.Esiste un modo standard per codificare una stringa .NET nella stringa JavaScript da utilizzare in MS Ajax?

Non voglio sfuggire solo le virgolette singole. Esiste una funzione standard che posso chiamare per evitare caratteri speciali da utilizzare in JavaScript?

string scriptstring = "alert('" + ex.Message + "');";   
ScriptManager.RegisterStartupScript(this, this.GetType(), "Alert", scriptstring , true); 

EDIT:

Grazie @tpeczek, il codice quasi ha funzionato per me :) ma con una leggera modifica (la fuga di apici) che funziona a meraviglia.

ho incluso la mia versione modificata qui ...

public class JSEncode 
{ 
    /// <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 '\\': 
        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(); 
    } 
} 

Come accennato qui sotto - fonte originale: here

risposta

9

Un probem con questa funzione è che non codifica caratteri che sono in genere out-of-band nell'incapsulare HTML ... quindi avresti problemi se provassi ad includere una stringa con " all'interno di un valore di attributo, o se avessi una stringa con la sequenza </script> all'interno di un elemento di script. Ciò potrebbe portare a script-injection e XSS.

si potrebbe aggiungere:

  case '<': 
       sb.Append("\\x3C"); 
       break; 
      case '"': 
       sb.Append("\\x22"); 
       break; 
      case '&': 
       sb.Append("\\x26"); 
       break; 

In generale sarebbe probabilmente meglio utilizzare un encoder JSON serie di preparare il proprio codificatore letterale di stringa JS. Ciò ti consentirà di passare qualsiasi tipo di dati semplice a JS anziché solo stringhe.

In .NET 3.5 si ottiene JavaScriptSerializer, tuttavia notare che mentre questo fa codificare < a \u003C (così l'uscita sarà adatto per l'uso in un elemento <script>), ma non si codificare & o ", quindi sarebbe necessario eseguire l'escape dell'HTML per includere tale contenuto in un valore di attributo e sarebbe necessario un wrapper CDATA per gli elementi dello script XHTML.

(In comune con molti codificatori JSON, non riesce a codificare i caratteri U + 2028 LINE SEPARATOR e U + 2029 PARAGRAPH SEPARATOR. Il codice precedente lo fa, a causa dell'escupazione di tutti i caratteri non ASCII. errori letterali quando questi caratteri sono inclusi in una stringa JS letterale, perché JavaScript li tratta in modo non corretto come una nuova riga ASCII)

+1

Grande scrittura. Si noti che 'JavaScriptSerializer' è anche disponibile in .NET 2 tramite la release out-of-band di ASP.NET AJAX 1.0 (http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ca9d90fa-e8c9- 42e3-aa19-08e2c027f5d6 & displaylang = it). – bdukes

+0

In tal caso non si utilizzerà 'HttpUtility.HtmlAttributeEncode (HttpUtility.JavaScriptStringEncode (unencodedString))' o 'HttpUtility.HtmlEncode (HttpUtility.JavaScriptStringEncode (unencodedString)) a ​​seconda del contesto? –

+0

@MartinBrown: è possibile utilizzare uno di quelli da inserire nell'attributo JS-in-HTML, sì (anche se in genere è una cattiva idea farlo). I metodi 'HtmlEncode' e' HtmlAttributeEncode' sono chiamati con curiosità; sembra che si dovrebbe lavorare meglio per i valori degli attributi e si dovrebbe lavorare meglio per il contenuto del testo, ma nella pratica non vi è alcuna distinzione tale da giudicare dalla fonte di riferimento. Sono solo due codificatori HTML implementati in modo arbitrario. – bobince

163

Hai dato un'occhiata a HttpUtility.JavaScriptStringEncode?

+9

In suvanzato perché è un'ottima risposta - funziona solo in .NET 4 anche se –

+5

Penso che quando c'è una funzione framework per un'attività specifica (come questa) è spesso più affidabile e accurata rispetto a quelli fai-da-te, quindi è meglio attenersi ad esso .. – Luke

+0

C'è una soluzione del genere in 3.5? –

Problemi correlati