2010-05-27 31 views
68

Tôi đang cố gắng chuyển đầu ra của một ngoại lệ SQL Server cho máy khách bằng phương thức RegisterStartUpScript của MS ScriptManager trong .NET 3.5. Điều này làm việc tốt cho một số lỗi nhưng khi ngoại lệ chứa dấu nháy đơn cảnh báo không thành công.Có cách nào tiêu chuẩn để mã hóa chuỗi .NET thành chuỗi JavaScript để sử dụng trong MS Ajax không?

Tôi không muốn chỉ thoát khỏi dấu nháy đơn. Có chức năng tiêu chuẩn nào tôi có thể gọi để thoát khỏi bất kỳ ký tự đặc biệt nào để sử dụng trong JavaScript không?

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

EDIT:

Cảm ơn @tpeczek, mã gần làm việc cho tôi :) nhưng với một điều chỉnh nhẹ (các thoát dấu nháy đơn) nó hoạt động một điều trị.

Tôi đã bao gồm phiên bản sửa đổi của tôi ở đây ...

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

Như đã đề cập dưới đây - nguồn gốc: here

Trả lời

9

Một probem với chức năng này là nó không mã hóa ký tự thường out-of-band trong việc đóng gói HTML ... vì vậy bạn sẽ gặp rắc rối nếu bạn cố gắng bao gồm một chuỗi với " bên trong một giá trị thuộc tính hoặc nếu bạn có một chuỗi với chuỗi </script> bên trong phần tử tập lệnh. Điều đó có thể dẫn đến kịch bản tiêm và XSS.

Bạn có thể thêm:

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

Nói chung nó có lẽ sẽ tốt hơn để sử dụng một bộ mã hóa JSON chuẩn hơn nấu chuỗi JS encoder đen của riêng bạn. Điều này sẽ cho phép bạn chuyển bất kỳ kiểu dữ liệu đơn giản nào sang JS hơn là chỉ các chuỗi.

Trong .NET 3.5 bạn sẽ có được JavaScriptSerializer, tuy nhiên lưu ý rằng trong khi này không mã hóa < để \u003C (do đó đầu ra sẽ phù hợp để sử dụng trong một phần tử <script>), nó không mã hóa & hoặc ", do đó, HTML-escape sẽ là cần thiết để bao gồm các nội dung như vậy trong một giá trị thuộc tính và một trình bao bọc CDATA sẽ là cần thiết cho các phần tử script XHTML.

(Nói chung với nhiều bộ mã hóa JSON, nó cũng không mã hóa các ký tự U + 2028 LINE SEPARATOR và U + 2029 PARAGRAPH SEPARATOR. Mã trên đây, do thoát khỏi tất cả các ký tự không phải ASCII. các lỗi 'theo nghĩa đen' khi các ký tự này được bao gồm trong một chuỗi ký tự JS, bởi vì JavaScript không xử lý chúng giống như một dòng mới ASCII.)

+1

Đăng ký tuyệt vời. Lưu ý rằng 'JavaScriptSerializer' cũng có sẵn trong .NET 2 thông qua bản phát hành out-of-band ASP.NET AJAX 1.0 (http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ca9d90fa-e8c9- 42e3-aa19-08e2c027f5d6 & displaylang = vi). – bdukes

+0

Trong trường hợp đó bạn sẽ không sử dụng 'HttpUtility.HtmlAttributeEncode (HttpUtility.JavaScriptStringEncode (unencodedString))' hoặc 'HttpUtility.HtmlEncode (HttpUtility.JavaScriptStringEncode (unencodedString))' phụ thuộc vào ngữ cảnh? –

+0

@MartinBrown: bạn có thể sử dụng một trong hai thứ đó để chèn vào thuộc tính JS-in-HTML, có (mặc dù thường là một ý tưởng tồi khi làm điều đó). Các phương thức 'HtmlEncode' và' HtmlAttributeEncode' được đặt tên một cách tò mò; có vẻ như người ta phải làm việc tốt hơn cho các giá trị thuộc tính và người ta phải làm việc tốt hơn cho nội dung văn bản, nhưng không có sự phân biệt như vậy trong thực tế đánh giá bởi nguồn tham chiếu. Chúng chỉ là hai bộ mã hóa HTML tùy ý-được thực hiện khác nhau. – bobince

163
+9

Được bình chọn bởi vì nó là một câu trả lời tuyệt vời - chỉ hoạt động trong .NET 4 mặc dù –

+5

Tôi nghĩ rằng khi có một chức năng khung cho một nhiệm vụ cụ thể (như thế này) nó thường đáng tin cậy hơn và chính xác hơn so với những người tự làm, nó tốt hơn với nó .. – Luke

+0

Có cách giải quyết nào giống như vậy trong 3.5 không? –

Các vấn đề liên quan