It's worth noting that although System.Web.VirtualPathUtility.ToAbsolute is very useful here, it is not a perfect replacement for Control.ResolveUrl.
There is at least one significant difference: Control.ResolveUrl handles Query Strings very nicely, but they cause VirtualPathUtility to throw an HttpException. This can be absolutely mystifying the first time it happens, especially if you're used to the way that Control.ResolveUrl works.
If you know the exact structure of the Query String you want to use, this is easy enough to work around, viz:
public static string GetUrl(int id)
{
string path = VirtualPathUtility.ToAbsolute("~/SomePage.aspx");
return string.Format("{0}?id={1}", path, id);
}
...but if the Query String is getting passed in from an unknown source then you're going to need to parse it out somehow. (Before you get too deep into that, note that System.Uri might be able to do it for you).
VirtualPathUtility.ToAbsolute("~/bar/baz?qux=123&quux=456", "/foo")
I get/foo/bar/baz?qux=123&quux=456
– Burrstone