2010-05-27 18 views
68

.NET 3.5'deki MS ScriptManager'ın RegisterStartUpScript yöntemini kullanarak istemciye bir SQL Server istisnası çıktısını vermeye çalışıyorum. Bu bazı hatalar için iyi çalışır, ancak istisna tek tırnak içerdiğinde uyarı başarısız olur.Bir .NET dizesini MS Ajax'da kullanılmak üzere JavaScript dizgisine kodlamak için standart bir yol var mı?

Sadece tek tırnaklardan kurtulmak istemiyorum. JavaScript'te kullanmak için özel karakterlerden kaçmak için arayabileceğim standart bir işlev var mı?

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

DÜZENLEME:

Teşekkür @tpeczek, kod neredeyse benim için çalıştı :) ama hafif bir değişiklik (tek tırnak kaçış) ile bir tedavi çalışır. Aşağıda belirtildiği gibi Benim burada değiştirilmiş versiyonu yer verdik

...

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(); 
    } 
} 

- orijinal kaynak: here

cevap

9

bu işlevle bir probem genellikle karakterler kodlamak olmamasıdır HTML'yi kapsülleyen bant dışı ... Böylece, bir öznitelik değerine " ile bir dize eklemeyi denediyseniz veya bir komut öğesi öğesinde </script> dizilimi olan bir dizeniz varsa sorun yaşayabilirsiniz. Bu, komut dosyası enjeksiyonu ve XSS'ye yol açabilir.

Sen ekleyebilirsiniz:

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

Genelde muhtemelen kendi JS dize kodlayıcı demlemek daha standart bir JSON kodlayıcı kullanmak daha iyi olacaktır. Bu, basit veri türlerini yalnızca dizelerden ziyade JS'ye iletmenize olanak tanır. .NET 3.5 olarak

sen JavaScriptSerializer olsun, ancak değil kodlamak & veya " yapar bu kodluyor <\u003C için yaptığı iken (çıktı bir <script> elemanı kullanılmak için uygun olacaktır) unutmayın, böyle bir içeriği bir öznitelik değerine eklemek için HTML-escaping gerekecek ve XHTML komut dosyası öğeleri için bir CDATA sarıcısına gerek duyulacaktır.

(Birçok JSON enkoderinde olduğu gibi, U + 2028 LINE SEPARATOR ve U + 2029 PARAGRAPH SEPARATOR karakterlerini de kodlamada başarısız olur. Yukarıdaki kod, ASCII olmayan tüm karakterlerden kaçış nedeniyle oluşur. Bu karakterleri bir JS dize değişmezine eklediğimizde, hatalar, JavaScript bir ASCII newline ile aynı şekilde davranmadığından dolayı.)

+1

Great write-up. "JavaScriptSerializer" ın .NET 2'de ASP.NET AJAX 1.0 bant dışı sürümü aracılığıyla da bulunduğunu unutmayın (http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ca9d90fa-e8c9- 42e3-aa19-08e2c027f5d6 & displaylang = tr). – bdukes

+0

Bu durumda, 'HttpUtility.HtmlAttributeEncode (HttpUtility.JavaScriptStringEncode (unencodedString)) 'veya' HttpUtility.HtmlEncode (HttpUtility.JavaScriptStringEncode (unencodedString)) 'ifadesini kullanmazsınız. –

+0

@MartinBrown: JS-in-HTML-özniteliğine enjekte etmek için bunlardan birini kullanabilirsiniz (evet, bunu yapmak genelde kötü bir fikir olsa da). HtmlEncode ve HtmlAttributeEncode yöntemleri merakla adlandırılır; nitelik değerleri için daha iyi çalışmalı ve bir tanesi metin içeriği için daha iyi çalışmalı gibi görünüyor, ancak kaynaklarda referans olarak değerlendirmede böyle bir ayrım yoktur. Bunlar sadece iki farklı şekilde uygulanan HTML kodlayıcıdır. – bobince

163

HttpUtility.JavaScriptStringEncode'a bir göz attınız mı?

+9

Mükemmel bir yanıtı olduğu için - Upvoted, yalnızca .NET 4 –

+5

olsa da, belirli bir görev için bir çerçeve işlevi olduğunda (bunun gibi), genellikle kendinizinkilerden daha güvenilir ve doğru olduğunu düşünüyorum. Onunla daha iyi sopa .. – Luke

+0

3.5 gibi bir geçici çözüm var mı? –

İlgili konular