tags:

views:

487

answers:

1

I want to convert a virtual file path to a physical file path in a windows service.

I know what the physical path is for the virtual directory, so I have the following function that works, but feels like a fudge:

public static string GetPhysicalPathFromVirtual(string rootPath, string virtualPath)
{
    int trailingSlash = virtualPath.IndexOf('/', 1) + 1;
    int length = virtualPath.Length - trailingSlash;
    string stripped = virtualPath.Substring(trailingSlash, length);
    stripped = stripped.Replace(@"/", @"\");
    return Path.Combine(rootPath, stripped);
}

The following example:

string test = FileHelper.GetPhysicalPathFromVirtual(@"T:\generateddocuments\output\", @"/virtualroot/folder/myfile.pdf");

Returns: T:\generateddocuments\output\folder\myfile.pdf

Is there a more elegant way to do this?

A: 

Uri class may be of help for your task.

Please note that using relative paths in services can expose a huge security hole so you should be very defensive when you code them.

Here's what I came up with:

public static string GetPhysicalPathFromVirtual(string rootPath, string virtualPath)
{
    const string mandatoryVirtualPrefix = "/virtualroot/";

    if (!virtualPath.StartsWith(mandatoryVirtualPrefix))
        throw new ArgumentOutOfRangeException(virtualPath, string.Format("Virtual '{0}' path must start with mandatory prefix '{1}'", virtualPath, mandatoryVirtualPrefix));

    var relativePath = virtualPath.Substring(mandatoryVirtualPrefix.Length);

    var rootUri = new Uri(rootPath, UriKind.Absolute);
    var relativeUri = new Uri(relativePath, UriKind.Relative);

    var absoluteUri = new Uri(rootUri, relativeUri);

    if (!rootUri.IsBaseOf(absoluteUri))
        throw new ArgumentOutOfRangeException(virtualPath, string.Format("Virtual path '{0}' can't be outside of root '{1}'", virtualPath, rootPath));

    return absoluteUri.AbsolutePath;
}
Konstantin Spirin
The problem with this is that you need to know the virtual root. In my case, I don't, and I don't want to pass it into the method either. That's why I search for the first folder path, and then remove it. Maybe the Uri class might help though. I'll try it out.
Junto
If you don't want to pass it, where do you want to get it from? Is it the same folder where exe is run from?
Konstantin Spirin