На основе моего личного опыта использования ASP.NET и поиска в Интернете. Я обнаружил, что метод ResolveUrl Пейджа принес нам серьезные проблемы.
Самая распространенная проблема заключается в том, что его нельзя использовать за пределами страницы или элемента управления.
Все остальные проблемы - это баги. Например, он не может правильно обрабатывать некоторые предоставленные вами URL-адреса. Например, попробуйте Page.ResolveUrl("~/test.aspx?param=http://www.test.com"). Результат тот же, что и введенная вами строка, без каких-либо изменений. Используя Reflector для просмотра кода asp.net, я обнаружил, что механизм преобразования относительных URL-адресов в абсолютные URL-адреса сначала ищет «://» в строке и, если находит, возвращает его напрямую. Таким образом, если вы передаете параметр с ://, строка запроса в порядке. Мы все знаем, что параметры строки запроса должны быть закодированы в urlencode, но если нет, то они все равно должны быть приемлемы для URL-адреса. Серьезно, проверьте свой браузер.
В Интернете рекомендуется использовать VirtualPathUtility.ToAbsolute, что весьма приятно и удобно, если вы передаете URL-адрес как строку запроса... в противном случае будет выдано исключение. Если это абсолютный URL-адрес, он также выдаст исключение!
Итак, я решил поискать окончательное решение.
Во-первых, я ищу хорошую переменную, которая предоставит нам виртуальный путь во время работы приложения без использования контекста страницы.
Я использовал HttpRuntime.AppDomainAppVirtualPath. Его можно использовать где угодно — даже в обратных вызовах таймера! В пути нет косой черты, ASP.NET странным образом устранил косую черту, но мы можем это исправить :-)
Затем я провел небольшое тестирование с использованием исходного кода ResolveUrl и выяснил, как заменить его на AppVirtualPath:
1. Если URL-адрес начинается с косой черты (/ или ), он не будет изменен!
2. Если URL-адрес начинается с 〜/, он будет заменен на AppVirtualPath.
3. Если URL-адрес является абсолютным, он не будет изменен.
4. В любом другом случае (даже начиная с 〜 вместо косой черты) URL-адрес будет добавлен к AppVirtualPath.
5. Всякий раз, когда он изменяет URL-адрес, он также исправляет косые черты. Удалите двойную косую черту и замените на /.
Код:
код
общедоступная статическая строка ResolveUrl (строка относительнаяUrl)
{
if (relativeUrl == null) создать новое исключение ArgumentNullException("relativeUrl");
if (relativeUrl.Length == 0 || относительныйUrl[0] == '/' ||
относительныйUrl[0] == '\') return относительныйUrl;
интервал idxOfScheme =
относительныйUrl.IndexOf(@"://", StringComparison.Ordinal);
если (idxOfScheme != -1)
{
int idxOfQM = относительныйUrl.IndexOf('?');
если (idxOfQM == -1 || idxOfQM > idxOfScheme) вернуть относительный URL;
}
StringBuilder sbUrl = новый StringBuilder();
sbUrl.Append(HttpRuntime.AppDomainAppVirtualPath);
if (sbUrl.Length == 0 || sbUrl[sbUrl.Length - 1] != '/') sbUrl.Append('/');
// уже нашел вопросительный знак? не трогайте!
Bool FoundQM = ложь;
bool FoundSlash // последний символ был косой чертой?
если (relativeUrl.Length > 1
&& относительный URL[0] == '~'
&& (relativeUrl[1] == '/' || относительныйUrl[1] == '\'))
{
относительныйUrl = относительныйUrl.Substring(2);
FoundSlash = Истина;
}
еще FoundSlash = ложь;
foreach (символ c в относительном URL)
{
если (!foundQM)
{
если (c == '?') FoundQM = true;
еще
{
если (c == '/' || c == '\')
{
если (foundSlash) продолжить;
еще
{
sbUrl.Append('/');
FoundSlash = Истина;
продолжать;
}
}
иначе, если (foundSlash) FoundSlash = false;
}
}
sbUrl.Append(c);
}
вернуть sbUrl.ToString();
}
После завершения кода и сравнения исходного теста ResolveUrl снова и снова я начал тестировать производительность... В большинстве случаев мой код выполнялся в 2,7 раза быстрее, чем исходный ResolveUrl! Я также протестировал его внутри цикла, выполнив код 100 000 раз с разными URL-адресами.
Ссылка на исходный текст: http://www.codeproject.com/KB/aspnet/resolveurl.aspx.
Автор: Чжу Цилинь Источник: http://zhuqil.cnblogs.com
Авторские права на эту статью принадлежат автору и Blog Park. Перепечатка приветствуется. Однако данное заявление должно быть сохранено без согласия автора, а ссылка на оригинальный текст должна быть предоставлена на видном месте на странице статьи. право на юридическую ответственность сохраняется.