I ended up with this. I take the request url, and use the position of Request.ApplicationRoot to discover the left part of the uri. Should work with applications hosted in a virtual directory "/example" or in the root "/".
private string GetFullUrl(string relativeUrl)
{
if (string.IsNullOrWhiteSpace(relativeUrl))
throw new ArgumentNullException("relativeUrl");
if (!relativeUrl.StartsWith("/"))
throw new ArgumentException("url should start with /", "relativeUrl");
string current = Request.Url.ToString();
string applicationPath = Request.ApplicationPath;
int applicationPathIndex = current.IndexOf(applicationPath, 10, StringComparison.InvariantCultureIgnoreCase);
// should not be possible
if (applicationPathIndex == -1) throw new InvalidOperationException("Unable to derive root path");
string basePath = current.Substring(0, applicationPathIndex);
string fullRoot = string.Concat(
basePath,
(applicationPath == "/") ? string.Empty : applicationPath,
relativeUrl);
return fullRoot;
}