2012-02-22 2 views
9

Мы храним кучу странных имен документов на нашем веб-сервере (люди загружают их), которые имеют разные символы, такие как пробелы, амперсанды и т. Д. Когда мы создаем ссылки на эти документы, нам нужно убежать от них, чтобы сервер мог искать файл по его необработанному имени в базе данных. Однако ни одна из встроенных функций escape-функции .NET не будет работать правильно во всех случаях.Как правильно вывести имя документа в .NET?

Возьмите документ Hello#There.docx:

UrlEncode будет правильно обращаться с этим:

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

Однако UrlEncode будет не ручка Hello There.docx правильно:

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

+ символ действителен только для параметров URL, а не d имена ocument. Интересно, что это действительно работает на тестовом веб-сервере Visual Studio, но не на IIS.

UrlPathEncode функция отлично работает для пространств:

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

Однако, он не избежит другие символы, такие как # характер:

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

Эта ссылка недействительна как # интерпретируется как хэш URL-адресов и даже не попадает на сервер.

Есть ли способ утилиты .NET для удаления всех не-буквенно-цифровых символов в имени документа, или мне нужно написать свой собственный?

+1

Как вы обрабатываете дубликаты, если пользователи загружают файлы с тем же именем? Не проще ли было бы машинное генерирование имен (например, guid, например) и сохранить дружественное, предоставленное пользователем имя в базе данных (вместе с сгенерированным именем файла)? –

+0

Вы, наверное, нужно что-то вроде этого [Удалить недопустимые символы из пути и имена файлов] [1] [1]: http://stackoverflow.com/questions/146134/how-to-remove-illegal-characters -from-path-and-filenames –

+0

@KirkWoll - Хороший вопрос :) URL * на самом деле * выглядит как '/ Docs/12345/My File.docx' - 12345 - это уникальный ключ, но мы хотим, чтобы IE« Сохранить как » ", чтобы сохранить файл с тем же именем, что и первоначально загруженный. Мы также проверяем соответствие имени файла ключевому слову, чтобы люди не могли просто угадать случайные документы (да, не на 100% безопасно, но достаточно хорошо). –

ответ

14

Посмотрите на Uri.EscapeDataString Method:

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

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

Вы, сэр, - джентльмен и ученый. –

+0

Обратите внимание, что если у вас есть иностранные символы, это преобразует его как экранированное представление UTF8, и в этом случае ваши пользователи могут по-прежнему получать забавные имена файлов в зависимости от приложения, которое открывает файл. Например, «Hélo.docx» (который корректно отображается браузерами) станет «H% C3% A9lo.docx». Но это может быть достаточно хорошо в этом случае (и, кстати, это так же с UrlEncode), но если «удобство для пользователя» является сильным требованием, я предлагаю вам также проверить это. –

+0

+1 но, не могли бы вы написать краткое описание того, когда использовать 'UrlEncode' vs' UrlPathEncode' vs 'EscapeDataString'? –

6

я бы подойти к нему по-другому: Не используйте имя документа как ключ в вашем просмотровых - используйте Guid или какой-либо другой параметр ID что вы можете сопоставить имя документа на диске в вашей базе. Это не только гарантировало бы уникальность, но и у вас также не было бы проблемы с побегом в первую очередь.

+0

Отличная точка зрения, я затронул эту проблему в своем комментарии выше. –

+2

Почему вы не можете использовать HTTP-заголовок 'content-disposition' в ответе? Это должно позволить вам установить имя файла – BrokenGlass

0

Вы можете использовать символ @, чтобы избежать строк. См. Ниже фрагменты кода.

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

Выход: \ п \ п \ п \ п

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

Выход: \ ДФ \ %%^\ ^) \ т %%

Этот вид форматирования очень полезно для путей и для создания регулярных выражений.

+2

Это связано с парсером C#, а не с приложением. – BoltClock

Смежные вопросы