2012-03-19 21 views
10

Trên trang web ASP.NET 4 và im nhận được lỗi sau khi cố tải dữ liệu từ cơ sở dữ liệu vào GridView.ASP.NET - Không thể dịch ký tự Unicode XXX tại chỉ mục YYY sang trang mã được chỉ định

Không thể dịch ký tự Unicode \ uD83D tại chỉ mục 49 sang trang mã được chỉ định.

Tôi đã phát hiện ra rằng điều này xảy ra khi một dòng dữ liệu chứa: Tiêu Tiêu Tiêu

Như tôi hiểu văn bản này không thể được dịch sang một phản ứng hợp lệ utf-8.

  1. Đó có thực sự là lý do không?

  2. Có cách nào để làm sạch văn bản trước khi tải nó vào GridView để ngăn chặn các lỗi như vậy không?


UPDATE:

Tôi có một số tiến bộ Tôi đã phát hiện ra tôi chỉ nhận được lỗi này khi tôi đang sử dụng phương pháp xâu vào một chuỗi. (Tôi đang sử dụng chuỗi con để hiển thị một phần văn bản dưới dạng bản xem trước cho người dùng).

Ví dụ trong một Web Form ASP.NET Tôi làm điều này:

String txt = test ; 

//txt string can also be created by 
String txt = char.ConvertFromUtf32(116) + char.ConvertFromUtf32(101) +char.ConvertFromUtf32(115) + char.ConvertFromUtf32(116) + char.ConvertFromUtf32(32) + char.ConvertFromUtf32(128148); 

// this works ok txt is shown in the webform label. 
Label1.Text = txt; 

//length is equal to 7. 
Label2.Text = txt.Length.ToString(); 

//causes exception - Unable to translate Unicode character \uD83D at index 5 to specified code page. 
Label3.Text = txt.Substring(0, 6); 

Tôi biết rằng chuỗi NET dựa trên utf-16 hỗ trợ cặp thay thế.

Khi tôi đang sử dụng chức năng SubString, tôi vô tình phá vỡ cặp thay thế và gây ra ngoại lệ. tôi phát hiện ra rằng tôi có thể sử dụng StringInfo lớp:

var si = new System.Globalization.StringInfo(txt); 
var l = si.LengthInTextElements; // length is equal to 6. 
Label3.Text = si.SubstringByTextElements(0, 5); //no exception! 

Một lựa chọn khác là chỉ cần xóa các cặp thay thế:

Label3.Text = ValidateUtf8(txt).Substring(0, 3); //no exception! 

    public static string ValidateUtf8(string txt) 
      { 
       StringBuilder sbOutput = new StringBuilder(); 
       char ch; 

       for (int i = 0; i < body.Length; i++) 
       { 
        ch = body[i]; 
        if ((ch >= 0x0020 && ch <= 0xD7FF) || 
          (ch >= 0xE000 && ch <= 0xFFFD) || 
          ch == 0x0009 || 
          ch == 0x000A || 
          ch == 0x000D) 
        { 
         sbOutput.Append(ch); 
        } 

       } 
       return sbOutput.ToString(); 
      } 

Đây có phải là thực sự là một vấn đề của cặp thay thế?

Nhân vật nào sử dụng cặp thay thế? có danh sách không?

Tôi có nên tiếp tục hỗ trợ cho các cặp thay thế không? sao tôi nên sử dụng StringInfo Class hoặc chỉ xóa các ký tự không hợp lệ?

Cảm ơn!

+0

RuSh: Tự hỏi bạn đã làm gì để khắc phục sự cố. Các phương pháp từ giải pháp của bạn hoạt động hoàn hảo cho trường hợp của tôi, trong khi các giải pháp từ LaserJesus dường như không làm sạch các nhân vật Uniciode xúc phạm. – Crulex

Trả lời

18

Bạn có thể thử mã hóa văn bản thành UTF8 trước tiên (trong sự kiện liên kết hàng hoặc nội dung tương tự). Đoạn mã sau sẽ mã hóa văn bản trong UTF8 và loại bỏ các ký tự không được mã hóa.

private static readonly Encoding Utf8Encoder = Encoding.GetEncoding(
    "UTF-8", 
    new EncoderReplacementFallback(string.Empty), 
    new DecoderExceptionFallback() 
); 

var utf8Text = Utf8Encoder.GetString(Utf8Encoder.GetBytes(text)); 
0

Ký tự U+1F60A là ký tự biểu tượng cảm xúc được giới thiệu trong Unicode 6.0. Đại diện UTF-16 của nó (SQL Server (bạn không đề cập đến cơ sở dữ liệu bạn đang sử dụng) sử dụng UCS-2 tương tự) là 0xD83D 0xDE0A sử dụng các ký tự thay thế.

Kể từ Unicode 6.0 được phát hành trong Oct 2010, của tôi đoán là SQL Server hoặc (ASP) .Net 4 hoặc chuyển đổi giữa dữ liệu SQL Server và.Dữ liệu mạng không hỗ trợ các điểm mã biểu tượng cảm xúc.

0

Tôi vừa phát hiện ra rằng Application Request Routing nếu được cài đặt trong IIS 7.5 sẽ buộc %2f được xử lý khác nhau, do đó gây ra vấn đề.

Xóa ARR đã giải quyết vấn đề này cho chúng tôi.

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