3

In my IHttpHandler class (for an .ashx page), I want to search a directory for certain files, and return relative urls. I can get the files, no problem:

string dirPath = context.Server.MapPath("~/mydirectory");
string[] files = Directory.GetFiles(dirPath, "*foo*.txt");
IEnumerable<string> relativeUrls = files.Select(f => WHAT GOES HERE? );

What is the easiest way to convert file paths to relative urls? If I were in an aspx page, I could say this.ResolveUrl(). I know I could do some string parsing and string replacement to get the relative url, but is there some built-in method that will take care of all of that for me?

Edit: To clarify, without doing my own string parsing, how do I go from this:

"E:\Webs\WebApp1\WebRoot\mydirectory\foo.txt"

to this:

"/mydirectory/foo.txt"

I'm looking for an existing method like:

public string GetRelativeUrl(string filePath) { }
gilly3
  • 87,962
  • 25
  • 144
  • 176
  • possible duplicate of [How do you convert a url to a virtual path in asp.net without manual string parsing?](http://stackoverflow.com/questions/493580/how-do-you-convert-a-url-to-a-virtual-path-in-asp-net-without-manual-string-parsi), or [How do I convert a file path to a URL in ASP.NET](http://stackoverflow.com/questions/16007/how-do-i-convert-a-file-path-to-a-url-in-asp-net) – Grant Thomas Apr 30 '11 at 23:48
  • That first link has to do with converting *from* a url to *virtual* path. I need to go from a file system path to a url. The second link uses `Control.ResolveUrl` which I can't use in a generic handler (or at least, I can't figure out how). – gilly3 May 01 '11 at 14:12
  • My bad, I had more than a few duplicates of this open in tabs, please allow me time to either find more or, failing that, posting a solution for you. – Grant Thomas May 01 '11 at 14:34

2 Answers2

1

I can imagine a lot of people having this question... My solution is:

public static string ResolveRelative(string url)
{
    var requestUrl = context.Request.Url;
    string baseUrl = string.Format("{0}://{1}{2}{3}", 
        requestUrl.Scheme, requestUrl.Host, 
        (requestUrl.IsDefaultPort ? "" : ":" + requestUrl.Port), 
        context.Request.ApplicationPath);

    if (toresolve.StartsWith("~"))
    {
        return baseUrl + toresolve.Substring(1);
    }
    else
    {
        return new Uri(new Uri(baseUrl), toresolve).ToString();
    }
}

update

Or from filename to virtual path (haven't tested it; you might need some code similar to ResoveRelative above as well... let me know if it works):

public static string GetUrl(string filename)
{
    if (filename.StartsWith(context.Request.PhysicalApplicationPath))
    {
        return context.Request.ApplicationPath +     
            filename.Substring(context.Request.PhysicalApplicationPath.Length);
    }
    else 
    {
        throw new ArgumentException("Incorrect physical path");
    }
}
atlaste
  • 30,418
  • 3
  • 57
  • 87
  • Your method returns an absolute url from a relative url. I'm looking for a relative url from a file path. – gilly3 Mar 14 '13 at 16:16
  • You can use the above method in combination with context.Request.PhysicalApplicationPath for that, which gives you the root of the application. – atlaste Mar 14 '13 at 17:34
0

try System.Web.Hosting.HostingEnvironment.MapPath method, its static and can be accessed everywhere in web application.

otakustay
  • 11,817
  • 4
  • 39
  • 43
  • That get's me the physical path, the same as `context.Server.MapPath()`. I already have the physical path and want to get the relative url, similar to `Control.ResolveUrl()`. – gilly3 May 01 '11 at 15:21