If you are looking for ResolveUrl outside of Page/Control, and even if you are not, this is for you.

Introduction/Background

From my personal experience using ASP.NET, and from searching the web, I have found that the ResolveUrlmethod of the Page control (and basically, Control) presents us with some serious problems.

The most common one is that you just cannot use it outside of the page or control context.

Other problems are just bugs. It will not correctly handle some of the URLs you'll give it. For example, tryPage.ResolveUrl("~/test.aspx?param=http://www.test.com"). The result is the very same input string... It will just do nothing. By looking into the ASP.NET code using Reflector, I found that all mechanisms that are supposed to convert the relative URLs to absolute URLs will search first for a "://" inside the string, and will return if found. So a query string is OK, unless you pass in a parameter with ://. Yes, I know that the query string parameter should be UrlEncoded, but if it isn't, it is still an acceptable URL. Seriously, check your browsers!

Other suggested methods on the web involve using VirtualPathUtility.ToAbsolute, which is pretty nice and handy, unless you pass in a query string with the URL... Because it will just throw an exception. It will also throw an exception for an absolute URL!

So I decided to find the ultimate solution.

Using the Code

First, I searched for the perfect variable that will give me the Application Virtual Path at runtime without a page context.

I found this to be HttpRuntime.AppDomainAppVirtualPath. It will work anywhere - even inside a timer callback! It gives the path without a trailing slash (ASP.NET makes a special effort to remove the trailing slash...), but that is OK, we can fix it 

Then, I did some tests on the original ResolveUrl code, and found where I need to replace what with theAppVirtualPath:

  1. When the URL begins with a slash (either / or \), it will not touch it!
  2. When the URL begins with ~/, it will replace it with the AppVirtualPath.
  3. When the URL is an absolute URL, it will not touch it. (ResolveUrl has a bug with this, as I said before...)
  4. In any other case (even beginning with ~, but not slash), it will append the URL to the AppVirtualPath.
  5. Whenever it modifies the URL, it also fixes up the slashes. Removes double slashes and replaces \ with /.

So I replicated all of that, but without the bugs. And here's the code:

 Collapse | Copy Code
public static string ResolveUrl(string relativeUrl)
{
if (relativeUrl == null) throw new ArgumentNullException("relativeUrl"); if (relativeUrl.Length == 0 || relativeUrl[0] == '/' || relativeUrl[0] == '\\')
return relativeUrl; int idxOfScheme = relativeUrl.IndexOf(@"://", StringComparison.Ordinal);
if (idxOfScheme != -1)
{
int idxOfQM = relativeUrl.IndexOf('?');
if (idxOfQM == -1 || idxOfQM > idxOfScheme) return relativeUrl;
} StringBuilder sbUrl = new StringBuilder();
sbUrl.Append(HttpRuntime.AppDomainAppVirtualPath);
if (sbUrl.Length == 0 || sbUrl[sbUrl.Length - 1] != '/') sbUrl.Append('/'); // found question mark already? query string, do not touch!
bool foundQM = false;
bool foundSlash; // the latest char was a slash?
if (relativeUrl.Length > 1
&& relativeUrl[0] == '~'
&& (relativeUrl[1] == '/' || relativeUrl[1] == '\\'))
{
relativeUrl = relativeUrl.Substring(2);
foundSlash = true;
}
else foundSlash = false;
foreach (char c in relativeUrl)
{
if (!foundQM)
{
if (c == '?') foundQM = true;
else
{
if (c == '/' || c == '\\')
{
if (foundSlash) continue;
else
{
sbUrl.Append('/');
foundSlash = true;
continue;
}
}
else if (foundSlash) foundSlash = false;
}
}
sbUrl.Append(c);
} return sbUrl.ToString();
}

Points of Interest

After completing the code and testing over and over again and comparing to the original ResolveUrl, I started to test for performance... In most cases, my code executed faster than the original ResolveUrl by 2.7 times! I also tested inside loops that executed the code 100000s of times on different kinds of URLs.

ResolveUrl in ASP.NET - The Perfect Solution的更多相关文章

  1. ASP.NET Core Logging Solution

    Serilog.Extensions.Logging.File This package makes it a one-liner - loggerFactory.AddFile() - to con ...

  2. [转]Bootstrap 3.0.0 with ASP.NET Web Forms – Step by Step – Without NuGet Package

    本文转自:http://www.mytecbits.com/microsoft/dot-net/bootstrap-3-0-0-with-asp-net-web-forms In my earlier ...

  3. .NET & C# & ASP.NET

    .NET && C# && ASP.NET https://docs.microsoft.com/zh-cn/dotnet/ .NET Documentation We ...

  4. error_Could not load file or assembly

    原文链接 Could you be missing the loaded assembly from your configuration file? Ensure you have somethin ...

  5. Android 自定义 ListView 显示网络上 JSON 格式歌曲列表

    本文内容 环境 项目结构 演示自定义 ListView 显示网络上 JSON 歌曲列表 参考资料 本文最开始看的是一个国人翻译的文章,没有源代码可下载,根据文中提供的代码片段,自己新建的项目(比较可恶 ...

  6. Thinking in Java——笔记(19)

    Enumerated Types Basic enum features When you create an enum, an associated class is produced for yo ...

  7. Cool!15个超炫的 CSS3 文本特效【上篇】

    每一个网页设计师都希望创建出让用户能够赏识的网站.当然,这是不可能满足每个人的口味的.幸运的是,我们有最强大的工具和资源.实际上,我们非常多的网站模板,框架,内容管理系统,先进的工具和其他的资源可以使 ...

  8. Day14 summary

    Since I am writing blog in Ubuntu which has not installed Chinese language package, this blog will b ...

  9. NodeJS 各websocket框架性能分析

    For a current project at WhoScored, I needed to learn JavaScript, Node.js and WebSocket channel, aft ...

随机推荐

  1. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(13)-权限设计

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(13)-权限设计 ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2):数据 ...

  2. 利用缓存、Timer间隔时间发送微信的实例,很有用的例子

    //Class WechatOfferExcutor 此类为微信触发类,属于上层调用类,其中有用到用静态变量缓存offer信息,Task异步执行发送方法等 using Newtonsoft.Json. ...

  3. php_公共方法01_传入数组_打印可见信息

    function decodeUnicode($str) { return preg_replace_callback('/\\\\u([0-9a-f]{4})/i', 'convert', $str ...

  4. 【MySQL案件】mysql登录-S失败

    1.1.1. mysql登录mysql时间,-S参数失效 [环境的叙述性说明] mysql5.5.14 [问题叙述性说明] 配置多个实例 实例1 实例2 datadir /home/mysql_330 ...

  5. android ndk通过遍历和删除文件

           在做移动开发过程,难免有些本地文件管理操作.例如,很常见app随着微博.微信要清除缓存功能,此功能是走app文件夹.然后删除所有缓存文件.使用java的File类能够实现本地文件遍历及删 ...

  6. .NET平台机器学习

    .NET平台机器学习资源汇总,有你想要的么? 接触机器学习1年多了,由于只会用C#堆代码,所以只关注.NET平台的资源,一边积累,一边收集,一边学习,所以在本站第101篇博客到来之际,分享给大家.部分 ...

  7. iOS_中国汉字到拼音_pinyin4objc

    最后效果图: ViewController.h // // ViewController.h // PinYin4Objc汉字转拼音演示demo // // Created by beyond on ...

  8. Web API 2:Action的返回类型

    Web API 2:Action的返回类型 Web API控制器中的Action方法有如下几种返回类型: void HttpResponseMessage IHttpActionResult 其它类型 ...

  9. NSString 常用分类

    #pragma mark 清空字符串中的空白字符 - (NSString *)trimString { return [self stringByTrimmingCharactersInSet:[NS ...

  10. Android EventBus现实 听说你out该

    转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/40794879.本文出自:[张鸿洋的博客] 1.概述 近期大家面试说常常被问到Ev ...