0

I am trying to upload an excel file into SQL server. The thing is I am stuck here

string fileName = Path.Combine(@"C:\", FileUpload1.FileName);
                    FileUpload1.SaveAs(fileName);

                    String excelConnString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0\"", fileName);

The line

string fileName = Path.Combine(@"C:\", FileUpload1.FileName);

gives pathname as C:\FileName for which I get an exception that access is denied, and from this

Why is access to the path denied?

I got to know that we can get these errors if the path is a directory. I know my path is wrong, but I am clueless as how to select the correct path for further processing.

My asp.net code is

<asp:FileUpload ID="FileUpload1" runat="server" Width="368px" />
        <p>
            <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
        </p>

When I referred this

https://www.c-sharpcorner.com/blogs/how-to-import-excel-data-in-sql-server-using-asp-net2

and

https://www.aspdotnet-suresh.com/2012/12/aspnet-how-to-get-full-file-path-from.html

and changed my code to

 string filename = Path.GetFileName(FileUpload1.PostedFile.FileName);
                    FileUpload1.SaveAs(Server.MapPath("Files/" + filename));
                    string filepath = "Files/" + filename;

I got Could not find a part of the path exception.

$exception    {"Could not find a part of the path 'C:\\Users\\AMEN\\source\\repos\\ExcelDatabase\\ExcelDatabase\\Files\\New Microsoft Excel Worksheet.xlsx'."}    System.IO.DirectoryNotFoundException

I then referred to the following also -

How to get the path of a file which is in file upload control in asp.net

but same error

I then inspected the path in the inspection and found out that it is incorrect --

C:\\Users\\AMEN\\source\\repos\\ExcelDatabase\\ExcelDatabase\\Files\\New Microsoft Excel Worksheet.xlsx'

I dont know why it entered the repos folder when I selected my excel from the desktop. But I know it appended file directory because of the following line

FileUpload1.SaveAs(Server.MapPath("Files/" + filename));

So I commented it out but then again too, it took the wrong path and I got the same exception . Please suggest me what should I do. Thanks

Anonymous
  • 113
  • 1
  • 2
  • 13
  • Server.MapPath returns the current physical directory of the file being executed. https://learn.microsoft.com/en-us/dotnet/api/system.web.httpserverutility.mappath?view=netframework-4.8 – Ashish.Wadekar Aug 25 '22 at 13:34
  • @Ashish.Wadekar After I Removed server.mappath, I got + $exception {"The SaveAs method is configured to require a rooted path, and the path 'Files/New Microsoft Excel Worksheet.xlsx' is not rooted."} System.Web.HttpException – Anonymous Aug 25 '22 at 14:27
  • @Ashish.Wadekar How can I get the actual directory of the file? – Anonymous Aug 25 '22 at 14:28
  • Check this, hope this helps - https://stackoverflow.com/questions/1089713/httppostedfile-saveas-error-rooted-path – Ashish.Wadekar Aug 25 '22 at 14:52
  • Where do you want to save that file? 1) Inside project directory 2) Any other location – Abdul Haseeb Aug 25 '22 at 15:39
  • Any other location. Currently, I have saved it on desktop. I don't really want to hard code the path. – Anonymous Aug 25 '22 at 15:39

1 Answers1

1

Ok, this OFTEN comes down to the developer flpping between URL, web based URL's, and then code behind.

The way it works (to avoid confusing) is:

Any URL, and links and sources used in a web page markup?

You use and think and consider that a valid URL path name.

So, if you have a folder on your web site called MyFiles, then any URL (web and markup) is this:

   www.mysite.com/MyFiles/dog.png

So, any reference in web markup = a web path, or relative web path.

But, in code behind?

You ALWAYS BUT ALWAYS use plain jane FULL windows path names in code to deal with a file.

So, failure to "flip" between the above contexts are what is the source of confusing in the vast majority of cases.

Next, keep in mind that file(s) up-loaded don't contain a path name, since information about the client side computer is not exposed and it not YOUR business anyway.

So, if I want a web link to any file in MyFiles - the it is web based URL (given our new rule above).

But, in code?

You can "translate" any web based URL to a internal plane jane windows file path, and code behind MUST USE windows path names, and they are in general to be FULL path names.

So, typical code to deal with a up-loaded file will look like this:

string filename = Path.GetFileName(FileUpload1.PostedFile.FileName);

string LocalFile = Server.MapPath(@"~/Files/" + filename);
 
FileUpload1.SaveAs(LocalFile);

So, two things:

You missed the "~/" to start from root.

You NEED to use @ for the string, since the slashes etc. are escaped characters in c#, and you WANT to avoid any issue in that area -- so use @"my string" for such cases that will have things like slashes in the string.

So above assumes you have a folder nested in the root web site, and it called MyFiles.

Often, and in most cases, you CAN save the file to ANY location you want (assuming the web server has permissions to the folder that NOT nested in or part of the web site).

This idea in fact is often used, since then no valid web URL's to the file(s) can be had or even exist from the web site to that file folder.

You can expose the file folder if you map a "virtual" folder in IIS, and this is often done. But EVEN better is to NOT map such folders to the web site, and then ALWAYS use code behind to allow downloading of such files, since then that is a big jump in security. (users cannot type in any URL to get and download a file in such folders. Only code behind can dish out such files to the users for download - exactly what we want for security in most cases.

So, use server.MapPath to convert the nested MyFiles folder into a valid windows path name. However, if the folder is outside of the web site, then you don't use Server.MapPath, but simple use and have your own windows path name to some file folder on the computer, or even on the same network that the web server is running on.

And the LAST suggeston to save bugs and world poverty?

BE VERY careful with Server.MapPath, it runs from your CURRENT PAGE context!

That means if you move a page (and more important code behind) to a different nesting then Server.MapPath will produce values RELATIVE to that page!!!!

As a result, to save world poverty and bugs? You would do VERY well to not use

 Server.MapPath(@"Files/")    -- bad idea!!!

And ALWAYS use this:

 Server.MapPath(@"~/Files/")   -- good idea.

So, MapPath uses the current nesting of the URL that your current page and more important the code behind is running under. So, avoid relative path names for MapPath. There are use cases where you want this to occur, but the WHOLE point is that relative context of the current page DOES occur when using mappath - it not absolute from root UNLESS YOU assume as such and introduce the "~/" part into this mix, and you should!!

Albert D. Kallal
  • 42,205
  • 3
  • 34
  • 51
  • 1
    You may need to make sure the target folder exists before saving – Hans Kesting Aug 25 '22 at 16:36
  • 1
    Sure, checking for the folder etc. - = good idea. But, I find for such discussions, ONCE I explain the context flip between URL based (markup) and that of code behind, then developers see and get this issue far more clear. Surprising how often the context between URL and code behind is not made CRYSTAL clear in the minds of the developer. The other source of bugs/issues? Server.MapPath is context based on the current page - so nesting of the current page will change results of MapPath - so including the root "~/" in most cases is a really good idea. – Albert D. Kallal Aug 25 '22 at 16:41