2012-02-22 21 views
9

Chúng tôi lưu trữ một loạt các tên tài liệu lạ trên máy chủ web của chúng tôi (mọi người tải lên) có các ký tự khác nhau như dấu cách, ký hiệu, v.v. Khi chúng tôi tạo liên kết đến các tài liệu này, chúng tôi cần phải thoát chúng để máy chủ có thể tra cứu tệp theo tên thô của nó trong cơ sở dữ liệu. Tuy nhiên, không có chức năng .NET nào được tích hợp sẵn sẽ hoạt động chính xác trong mọi trường hợp.Làm thế nào để bạn thoát đúng tên tài liệu trong .NET?

Lấy tài liệu Hello#There.docx:

UrlEncode sẽ xử lý việc này một cách chính xác:

HttpUtility.UrlEncode("Hello#There"); 
"Hello%23There" 

Tuy nhiên, UrlEncode sẽ không xử lý Hello There.docx một cách chính xác:

HttpUtility.UrlEncode("Hello There.docx"); 
"Hello+There.docx" 

Biểu tượng + chỉ có giá trị cho thông số URL, không phải d tên tượng đài. Điều thú vị đủ, điều này thực sự hoạt động trên máy chủ web Visual Studio thử nghiệm nhưng không phải trên IIS.

Chức năng UrlPathEncode hoạt động tốt cho các không gian:

HttpUtility.UrlPathEncode("Hello There.docx"); 
"Hello%20There.docx" 

Tuy nhiên, nó sẽ không thoát khỏi nhân vật khác như # nhân vật:

HttpUtility.UrlPathEncode("Hello#There.docx"); 
"Hello#There.docx" 

liên kết này không hợp lệ như # được hiểu như là một băm URL và thậm chí không bao giờ được vào máy chủ.

Có phương pháp tiện ích .NET nào để thoát khỏi tất cả các ký tự không phải chữ và số trong tên tài liệu không hoặc tôi có phải viết của riêng mình không?

+1

Làm thế nào để bạn xử lý các dups nếu người dùng tải lên các tệp có cùng tên? Chẳng phải sẽ dễ dàng hơn khi tạo ra các tên (ví dụ như một guid) và lưu trữ tên thân thiện, do người dùng cung cấp trong cơ sở dữ liệu (cùng với tên tệp được tạo)? –

+0

Bạn có lẽ cần một cái gì đó như thế này [Di chuyển nhân vật bất hợp pháp Từ Đường dẫn và tên tập tin] [1] [1]: http://stackoverflow.com/questions/146134/how-to-remove-illegal-characters -from-path-và-filenames –

+0

@KirkWoll - Câu hỏi hay :) URL * thực sự * trông giống như '/ Documents/12345/My File.docx' - 12345 là khóa duy nhất, nhưng chúng tôi muốn IE" Lưu dưới dạng "hộp thoại để lưu tệp có cùng tên như được tải lên ban đầu. Chúng tôi cũng xác minh tên tệp khớp với khóa để ngăn mọi người chỉ đoán các tài liệu ngẫu nhiên (yea, không an toàn 100% nhưng đủ tốt) .. –

Trả lời

14

Có một cái nhìn tại Uri.EscapeDataString Method:

Uri.EscapeDataString("Hello There.docx") // "Hello%20There.docx" 

Uri.EscapeDataString("Hello#There.docx") // "Hello%23There.docx" 
+1

Bạn, thưa bạn, là một quý ông và một học giả. –

+0

Lưu ý nếu bạn có ký tự nước ngoài, điều này sẽ chuyển đổi nó thành biểu tượng thoát UTF8, trong trường hợp đó người dùng của bạn vẫn có thể nhận được tên tệp hài hước tùy thuộc vào ứng dụng mở tệp. Ví dụ: "Hélo.docx" (được hiển thị chính xác theo trình duyệt), sẽ trở thành "H% C3% A9lo.docx". Nhưng điều này có thể là đủ tốt trong trường hợp này (và btw này là như nhau với UrlEncode), nhưng nếu "người dùng thân thiện" là một yêu cầu mạnh mẽ, tôi đề nghị bạn kiểm tra xem đó là tốt. –

+0

+1 nhưng, bạn có thể viết tóm tắt nhanh về thời điểm sử dụng 'UrlEncode' so với' UrlPathEncode' so với 'EscapeDataString' không? –

6

tôi sẽ tiếp cận nó một cách khác nhau: Không sử dụng tên tài liệu như quan trọng trong việc bạn nhìn lên - sử dụng một Guid hoặc một số tham số id khác bạn có thể ánh xạ tới tên tài liệu trên đĩa trong cơ sở dữ liệu của bạn. Điều đó không chỉ đảm bảo tính duy nhất nhưng bạn cũng sẽ không gặp vấn đề này khi trốn thoát ngay từ đầu.

+0

Điểm tuyệt vời, tôi đã giải quyết vấn đề đó trong nhận xét của tôi ở trên. –

+2

Tại sao bạn không thể sử dụng tiêu đề HTTP 'nội dung bố trí 'trong phản hồi của mình? Điều đó sẽ cho phép bạn đặt tên tệp – BrokenGlass

0

Bạn có thể sử dụng @ ký tự để thoát chuỗi. Xem các đoạn mã dưới đây.

string str = @"\n\n\n\n"; 
Console.WriteLine(str); 

Output: \ n \ n \ n \ n

string str1 = @"\df\%%^\^\)\t%%"; 
Console.WriteLine(str1); 

Output: \ df \ %%^\ ^) \ t %%

Đây là loại định dạng là rất hữu ích cho tên đường dẫn và tạo regex.

+2

Điều này phải làm với trình phân tích cú pháp C#, không phải ứng dụng. – BoltClock

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