locked
HttpContext.Current.Server.MapPath fails for long file names RRS feed

  • Question

  • User140365425 posted

    Hello:

      I'm sure this has been discussed before, but I could not find a reference to the topic. Basically, Server.MApPath fails for long file names. Here is the exception log. The file path is more than 260 characters. Is there a work around for long file names using the above method. Here is the exception trace:

    {System.IO.PathTooLongException: The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
       at System.IO.PathHelper.GetFullPathName()
       at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength)
       at System.IO.Path.GetFullPathInternal(String path)
       at System.Security.Util.StringExpressionSet.CanonicalizePath(String path, Boolean needFullPath)
       at System.Security.Util.StringExpressionSet.CreateListFromExpressions(String[] str, Boolean needFullPath)
       at System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList)
       at System.Security.Permissions.FileIOPermission..ctor(FileIOPermissionAccess access, String path)
       at System.Web.InternalSecurityPermissions.PathDiscovery(String path)
       at System.Web.HttpRequest.MapPath(VirtualPath virtualPath, VirtualPath baseVirtualDir, Boolean allowCrossAppMapping)
       at System.Web.HttpRequest.MapPath(VirtualPath virtualPath)
       at System.Web.HttpServerUtility.MapPath(String path)
       at VI.Reporting.Manager.ReportPage.copyImagesString(String xmlString)}

    We tried appending \\?\\ to the relative path, but the MapPath throws exception complaining about the \\. Is there way to handle the long path names without redesigning the entire application?

    Thanks

    --Z--

    Wednesday, August 1, 2012 1:51 PM

Answers

  • User-434868552 posted

    @ zyzzyxx

    (a) do you actually use the value of "fileName"?:

    // get the file name from the url pathname
    String fileName = Path.GetFileName(mypath);

    (b) WHAT is the value of "fileName" (see (a) above) ?

    (c) i've split the following over several lines to make it easier to read; it's 382 characters.

    mypath =
    "/filesystem/
    FileRoot/
    0123456789-01234567890123456789000000000011111111111222222222221=1a0123456789-012345678901234567890000000000111111111112222222222=0123456789-0123456789012345678900000000001111111111122222222222a/
    1.3.6.1.4.1.25403.2200303521616.13088.20120730010120.1/
    1.2.840.113747.1343838899.2680.2728.443921523855252.0/
    1.2.840.113747.1343838899.2680.2728.443921523855252.2.png"

    looking at some of the component parts of mypath:

    String mypathA = "0123456789-01234567890123456789000000000011111111111222222222221=1a0123456789-012345678901234567890000000000111111111112222222222=0123456789-0123456789012345678900000000001111111111122222222222a";                      // Length 194
    String mypathB = "/1.3.6.1.4.1.25403.2200303521616.13088.20120730010120.1";    // Length 55 
    String mypathC = "/1.2.840.113747.1343838899.2680.2728.443921523855252.0";     // Length 54
    String mypathD = "/1.2.840.113747.1343838899.2680.2728.443921523855252.2.png"; // Length 58

          194+55+54 == 303 !!!  ...

    How was your customer even able to successfully store the graphic
      1.2.840.113747.1343838899.2680.2728.443921523855252.2.png
    into the file system?

      ----------------------------------------------------

    TIMTOWTDI   =.  there is more than one way to do it

    zyzzyxx, will your customer allow you to mirror the graphics files in a shorter directory?

    think of the equivalent of TinyURL links ...

    you could then perform a table lookup on your long path to get a short path, example:

    0123456789-01234567890123456789000000000011111111111222222222221=1a0123456789-012345678901234567890000000000111111111112222222222=0123456789-0123456789012345678900000000001111111111122222222222a/
    1.3.6.1.4.1.25403.2200303521616.13088.20120730010120.1/
    1.2.840.113747.1343838899.2680.2728.443921523855252.0/
    1.2.840.113747.1343838899.2680.2728.443921523855252.2.png

    might mirror as

    xyz/
    abc/
    pqr/
    1.2.840.113747.1343838899.2680.2728.443921523855252.2.png

    FWIW, it appears that you're trying to make a legacy non-web application into an internet application ???

    BTW, this is interesting:
    http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url

    g.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, August 2, 2012 11:17 AM
  • User-434868552 posted

    @ zyzzyxx

    we had to add an Unmanaged long file name handler

    FWIW, it appears the you might need to extend your Unmanaged long file name handler to be useful to your web application.

    QUESTION:  have you tried   \\?\ yet? (three slashes instead of four).

    were able to store file path up to 32K

    please see the stackoverflow link from my previous post ... looks like no matter what you do, your total URL length will need to stay below 2000 characters ... your customers have no control over that because it appears to be a generic browser limitation.

    g.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, August 2, 2012 4:20 PM

All replies

  • User-434868552 posted

    @ zyzzyxx

    We tried appending \\?\\ <=====

     

    AFAIK, the prefix is
    \\?\     (total THREE slashes) not
    \\?\\

    see http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath
    at "Naming FIles, Paths, and Namespace".

    zyzzyxx  Tip:  in addition to your stacktrace, it's often useful for you to show the relevant parts of your code, highlighted the offending line(s).

    g.

    Wednesday, August 1, 2012 2:45 PM
  • User-1910946339 posted

    The rules are quite complex but basically everything fails when the file path is more than ~260 characters.  (For example, try opening the file in Word or some other desktop application, it will fail).  Nothing to do with Server.MapPath its more to do with the actual file system.

    You could try sharing a folder that is some distance down the tree, map a drive to that shared folder and then access the file through the mapped drive.  It's just a thought - I haven't tested this approach.

    Basically, the answer is to make the file path shorter.Frown

    Wednesday, August 1, 2012 5:56 PM
  • User-434868552 posted

    basically everything fails when the file path is more than ~260 characters.

    FWIW, http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#maxpath states otherwise:

    "The Windows API has many functions that also have Unicode versions to permit an extended-length path for a maximum total path length of 32,767 characters."

    "To specify an extended-length path, use the "\\?\" prefix. For example, "\\?\D:\very long path"."

    Regardless, i absolutely agree with Paul Linton:

    make the file path shorter.Frown

    The reason that i agree with Paul is that even if you are successful, chances are other programs will likely choke ... e.g.:

    as an experiment, i created a file deeply buried ...

    unfortunately, DIR will not dive below the first part of the path:

    String veryLongPath =

    @"C:\DEEPNE~1\DIRECT~1\EXPERI~1\123456~1\123456~1\123456~2\123456~1\123456~1\123456~1\123456~1\123456~1\123456~2\123456~1\_NEXT_~1\123456~1\123456~1\123456~1\123456~1\123456~1\123456~1\123456~1\123456~1\123456~1\123456~1\_ANOTH~1\123456~1\123456789x\123456789_";
    Console.WriteLine (veryLongPath.Length);  // length is 258


    C:\DEEPNE~1\DIRECT~1\EXPERI~1\123456~1\123456~1\123456~2\123456~1\123456~1\12345
    6~1\123456~1\123456~1\123456~2\123456~1\_NEXT_~1\123456~1\123456~1\123456~1\1234
    56~1\123456~1\123456~1\123456~1\123456~1\123456~1\123456~1\_ANOTH~1\123456~1\123
    456789x\123456789_>dir
    The filename or extension is too long.

    BOTTOM  LINE:   like Paul suggests, keep your path short and manageable.

    g.

    Wednesday, August 1, 2012 10:13 PM
  • User140365425 posted

    Shortening a path is not an option. Try explaining that to Japanese Customers.

    The offending part of the code goes like this:

    This is the URL.

    mypath = "/filesystem/FileRoot/0123456789-01234567890123456789000000000011111111111222222222221=1a0123456789-012345678901234567890000000000111111111112222222222=0123456789-0123456789012345678900000000001111111111122222222222a/1.3.6.1.4.1.25403.2200303521616.13088.20120730010120.1/1.2.840.113747.1343838899.2680.2728.443921523855252.0/1.2.840.113747.1343838899.2680.2728.443921523855252.2.png"

    // 1. create origin path
                                // get the file name from the url pathname
                                String fileName = Path.GetFileName(mypath);
                                // get the relative path from the url pathname, then get the absolute path name
                                Uri myURL = new Uri(mypath);
                                String myRelativePath = myURL.AbsolutePath;
    
    //Offending code             String myAbsolutePath = HttpContext.Current.Server.MapPath(myRelativePath);
    Thursday, August 2, 2012 8:52 AM
  • User-434868552 posted

    @ zyzzyxx

    (a) do you actually use the value of "fileName"?:

    // get the file name from the url pathname
    String fileName = Path.GetFileName(mypath);

    (b) WHAT is the value of "fileName" (see (a) above) ?

    (c) i've split the following over several lines to make it easier to read; it's 382 characters.

    mypath =
    "/filesystem/
    FileRoot/
    0123456789-01234567890123456789000000000011111111111222222222221=1a0123456789-012345678901234567890000000000111111111112222222222=0123456789-0123456789012345678900000000001111111111122222222222a/
    1.3.6.1.4.1.25403.2200303521616.13088.20120730010120.1/
    1.2.840.113747.1343838899.2680.2728.443921523855252.0/
    1.2.840.113747.1343838899.2680.2728.443921523855252.2.png"

    looking at some of the component parts of mypath:

    String mypathA = "0123456789-01234567890123456789000000000011111111111222222222221=1a0123456789-012345678901234567890000000000111111111112222222222=0123456789-0123456789012345678900000000001111111111122222222222a";                      // Length 194
    String mypathB = "/1.3.6.1.4.1.25403.2200303521616.13088.20120730010120.1";    // Length 55 
    String mypathC = "/1.2.840.113747.1343838899.2680.2728.443921523855252.0";     // Length 54
    String mypathD = "/1.2.840.113747.1343838899.2680.2728.443921523855252.2.png"; // Length 58

          194+55+54 == 303 !!!  ...

    How was your customer even able to successfully store the graphic
      1.2.840.113747.1343838899.2680.2728.443921523855252.2.png
    into the file system?

      ----------------------------------------------------

    TIMTOWTDI   =.  there is more than one way to do it

    zyzzyxx, will your customer allow you to mirror the graphics files in a shorter directory?

    think of the equivalent of TinyURL links ...

    you could then perform a table lookup on your long path to get a short path, example:

    0123456789-01234567890123456789000000000011111111111222222222221=1a0123456789-012345678901234567890000000000111111111112222222222=0123456789-0123456789012345678900000000001111111111122222222222a/
    1.3.6.1.4.1.25403.2200303521616.13088.20120730010120.1/
    1.2.840.113747.1343838899.2680.2728.443921523855252.0/
    1.2.840.113747.1343838899.2680.2728.443921523855252.2.png

    might mirror as

    xyz/
    abc/
    pqr/
    1.2.840.113747.1343838899.2680.2728.443921523855252.2.png

    FWIW, it appears that you're trying to make a legacy non-web application into an internet application ???

    BTW, this is interesting:
    http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url

    g.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, August 2, 2012 11:17 AM
  • User140365425 posted

    They were not, so we had to add an Unmanaged long file name handler. That way were able to store file path up to 32K.

    Now, I have to mimic the same thing, because the file names/directory are DICOM's UIDs and they cannot be changed.

    The server.MapPath works for any virtual path < 266 characters but fails for filepaths shown in the previous posts..

     

     

    Thursday, August 2, 2012 3:56 PM
  • User-434868552 posted

    @ zyzzyxx

    we had to add an Unmanaged long file name handler

    FWIW, it appears the you might need to extend your Unmanaged long file name handler to be useful to your web application.

    QUESTION:  have you tried   \\?\ yet? (three slashes instead of four).

    were able to store file path up to 32K

    please see the stackoverflow link from my previous post ... looks like no matter what you do, your total URL length will need to stay below 2000 characters ... your customers have no control over that because it appears to be a generic browser limitation.

    g.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Thursday, August 2, 2012 4:20 PM