2009-03-30 29 views
10

Tôi có aa chuỗi trong C# khởi tạo như sau:Tại sao điều này xuất hiện trong C# chuỗi của tôi: Â £

string strVal = "£2000"; 

Tuy nhiên bất cứ khi nào tôi viết chuỗi này ra sau đây được viết:

 £ 2000

Nó không làm điều này với đô la.

Một chút ví dụ về mã Tôi đang sử dụng để viết ra các giá trị:

System.IO.File.AppendAllText(HttpContext.Current.Server.MapPath("/logging.txt"), strVal); 

Tôi đoán nó là cái gì để làm với nội địa hóa nhưng nếu C# chuỗi chỉ là unicode chắc chắn điều này chỉ nên làm việc?

CLARIFICATION: Chỉ cần thêm một chút thông tin, câu trả lời của Jon Skeet là chính xác, tuy nhiên tôi cũng gặp phải sự cố khi tôi URLEncode chuỗi. Có cách nào để ngăn chặn điều này không?

Vì vậy, chuỗi URL được mã hóa trông như thế này:

"% c2% a32000"

% c2 = Â % a3 = £

Nếu tôi mã hóa như ASCII các £ đi ra như ?

Có thêm ý tưởng nào nữa không?

Trả lời

6

Bộ ký tự mặc định của URL khi được sử dụng trong các trang HTML và trong tiêu đề HTTP được gọi là ISO-8859-1 hoặc ISO Latin-1.

Nó không giống như UTF-8, và nó không giống như ASCII, nhưng nó phù hợp với một byte cho mỗi ký tự. Phạm vi 0 đến 127 rất giống ASCII và toàn bộ dải từ 0 đến 255 giống với phạm vi 0000-00FF của Unicode.

Vì vậy, bạn có thể tạo nó từ chuỗi C# bằng cách truyền từng ký tự thành một byte hoặc bạn có thể sử dụng Encoding.GetEncoding("iso-8859-1") để có đối tượng thực hiện chuyển đổi cho bạn.

(Trong bộ ký tự này, biểu tượng bảng Anh là 163.)

nền

The RFC says rằng unencoded văn bản phải được giới hạn trong 7-bit phạm vi ASCII Mỹ truyền thống, và bất cứ điều gì khác (cộng với các ký tự phân cách URL đặc biệt) phải được mã hóa. Nhưng nó lại mở câu hỏi về ký tự được thiết lập để sử dụng cho nửa trên của phạm vi 8 bit, làm cho nó phụ thuộc vào ngữ cảnh mà URL xuất hiện.

Và bối cảnh đó được xác định bởi hai tiêu chuẩn khác, HTTP và HTML, quy định cụ thể bộ ký tự mặc định và cùng nhau tạo ra một lực thực tế không thể cưỡng lại trên người triển khai để giả sử thanh địa chỉ chứa phần trăm mã hóa tham chiếu đến ISO -8859-1.

ISO-8859-1 is the character set of text-based content sent via HTTP trừ khi được chỉ định khác. Vì vậy, vào thời điểm một chuỗi URL xuất hiện trong tiêu đề HTTP GET, nó phải nằm trong ISO-8859-1.

Yếu tố khác là HTML cũng sử dụng ISO-8859-1 làm mặc định và URL thường bắt nguồn dưới dạng liên kết trong trang HTML. Vì vậy, khi bạn tạo một trang HTML đơn giản tối thiểu trong Notepad, các URL bạn nhập vào tệp đó nằm trong ISO-8859-1.

Đôi khi nó được mô tả là "lỗ hổng" trong các tiêu chuẩn, nhưng nó không thực sự; nó chỉ là HTML/HTTP điền vào chỗ trống của RFC cho URL.

Do đó, ví dụ, những lời khuyên trên this page:

mã hóa URL của một nhân vật bao gồm của một biểu tượng "%", tiếp theo là hai chữ số thập lục phân đại diện (case-insensitive) của điểm mã ISO-Latin cho ký tự.

(ISO-Latin là tên khác cho IS-8859-1).

Rất nhiều lý thuyết. Dán nó vào notepad, lưu nó dưới dạng tệp .html và mở nó trong một vài trình duyệt. Nhấp vào liên kết và Google sẽ tìm kiếm bảng Anh.

<HTML> 
    <BODY> 
    <A href="http://www.google.com/search?q=%a3">Test</A> 
    </BODY> 
</HTML> 

Nó hoạt động trong IE, Firefox, Apple Safari, Google Chrome - Hiện tại tôi không có bất kỳ sản phẩm nào khác.

+0

Điều này giải quyết được vấn đề của tôi một cách hoàn hảo. Chỉ cần đặt mã hóa iso-8859-1 trên UrlEncode của tôi. –

+0

Bạn có nguồn thông tin về mã hóa ký tự mặc định của URL không? Tôi nghĩ đó là một trong những điều khó chịu. Tôi không tranh chấp nó, nhưng tôi muốn xem nơi nó được chỉ định là mặc định. Btw, bạn cũng có thể sử dụng Encoding.GetEncoding (28591) để lấy ISO-8859-1. –

+0

Tôi quan tâm vì sao URLEncode không tự động thực hiện chuyển đổi này.Vì các chuỗi trong C# là UTF-8 nên nó sẽ khá trực quan để các phương thức URLEncode chấp nhận một chuỗi như vậy và mã hóa nó một cách chính xác. Thay vì rơi xuống trừ khi tôi chỉ định mã hóa chính xác theo cách thủ công? –

7

AppendAllText đang viết văn bản bằng UTF-8.

Bạn đang sử dụng cái gì để xem nó? Rất có thể đó là một cái gì đó không hiểu UTF-8, hoặc không thử UTF-8 đầu tiên. Cho trình soạn thảo/người xem của bạn biết đó là tệp UTF-8 và tất cả sẽ tốt. Ngoài ra, sử dụng tình trạng quá tải của AppendAllText cho phép bạn chỉ định mã hóa và sử dụng mã hóa nào sẽ thuận tiện nhất cho bạn.

EDIT: Để trả lời câu hỏi đã chỉnh sửa của bạn, lý do không thành công khi bạn mã hóa bằng ASCII là £ không nằm trong bộ ký tự ASCII (là Unicode 0-127).

Mã hóa URL cũng đang sử dụng UTF-8, theo giao diện của nó. Một lần nữa, nếu bạn muốn sử dụng một mã hóa khác, hãy chỉ định nó cho quá tải HttpUtility.UrlEncode chấp nhận mã hóa.

0

Tôi nhận thấy rằng điều này chỉ xảy ra khi chuỗi dài được sử dụng (hơn 4000) ký tự. Giải pháp của tôi là khi nhận được tham số trong cơ sở dữ liệu, tôi chỉ đơn giản là thay thế các dấu hiệu không có gì. Hãy cẩn thận, có thể thực sự cần thiết, và nếu đó là trường hợp giải pháp này là không thích hợp.

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