FileUpload - Verifying that an actual file was uploaded - c#

I have a FileUpload control (FileUpload1) on my web form, as well as a "Sumbit" button, a label, and a hidden field that contains a UserID. I have the following code in the button's click event:
string path = Server.MapPath("~/userfiles/");
if (FileUpload.HasFile)
{
try
{
FileUpload1.SaveAs(path + UserID.Value + "/image.jpg");
}
catch
{
Label1.Text = "* unable to upload file";
Label1.Visible = true;
}
}
It works great if I upload an actual file. However, if I type a non-existent filename (for example, "c:\a.jpg", which does not exist on my computer) into the FileUpload's textbox, and click the Sumbit button, HasFile still returns true. Furthermore, SaveAs() does not throw any exceptions, and it is a void function that returns no value indicating success or failure. How do I tell whether a file was actually uploaded?

Just check to see if it exists.
if(File.Exists(myFile)){
//it was uploaded.
}

You could check FileUpload.PostedFile.ContentLength property

You could check if the file exists using File.Exists before calling SaveAs.

Hmmm....
Not sure I understand. First, in your code, FileUpload.HasFile won't compile. If should be FileUpload1.HasFile.
When I correct this, and run your code, this line returns false if the file does not exist...
You can check if file exists after uploading using File.Exists(path); The file object is part of System.IO.

This is not about your actual question, but you should validate any user input, especially if you want users to upload files to a virtual folder on your webserver. You should at least check whether the content type of the file is the one you expect, or - even better, filter (resize) the image using the classes available in the .NET framework.
If you don't do so users may share arbitrary content via your site or place malicious files (e.g. images containing script which might get executed by certain web browsers) on your server.
With additional validation you will also be able to validate if there has actually been content sent.
AND: A really severe vulnerability opens up when you build the save path by concatenating input from a form field (I assume UserID.Value is the POST parameter you mention?). This allows users to decide where to store the content on your server, and, even worse, be able to overwrite existing files!!!

Related

C# - interop excel

I want to filling windows form data to excel. the end of code I give validation so if the filename exist on specific location it would not save it again
string savingNewForm = "C:\\temp\\" + temp;
if (File.Exists(savingNewForm))
{
MessageBox.Show("File already exist!");
oBook.Close();
oApp.Quit();
}
else
{
oBook.SaveAs(savingNewForm);
oBook.Close();
oApp.Quit();
MessageBox.Show("Your file saved");
}
but when user save the same filename it give error.
I think the main problem is on if (File.Exists(savingNewForm)) cause it's not checking if the filename exist or not, instead it goes to else and give a popup excel asking if I want to replace or not.
What is the value of temp? There could be a problem if the filename contains invalid characters or is too long, etc.
From MSDN:
The Exists method should not be used for path validation, this method
merely checks if the file specified in path exists. Passing an invalid
path to Exists returns false.
If path describes a directory, this method returns false.
The Exists method returns false if any error occurs while trying to determine if the specified file exists.
If the directory doesn't exist or if the user does not have permission to read the file (maybe it's locked) then File.Exists() will return false.
If it's an issue with the existence of the file, see Softerware's answer. If you want Excel to not ask the user to overwrite, try:
oApp.DisplayAlerts = false;
Although I haven't worked with your excel library, suggest you to try workaround:
save into another file;
remove target;
move saved file to target filename.
Error on file removing will be more informative anycase.

How to read file in C# from POST data from web

Basically, I'm building a website that allows user to upload file.
From the front end (JavaScript), the user will browse a file, I can get the site to send POST data (the parameter "UploadInput" and it's value, which the value is the file)
In the backend (C#), I want to make a copy of the file and save it in a specific path.
Below is the way I did it.
var files = Request.Files;
file[0].SaveAs("\temp\\" + file[0].FileName);
The problem I ran into is that I got the error message saying index out of range. I tried Response.Write(files.Count) and it gives me 0 instead of 1.
I'm wondering where I did wrong and how to fix it, or if there's a better way of doing it.
Thanks!
Edit:
I am using HttpFox to debug. From HttpFox, I can see that under POST data, parameter is "UploadInput" and the value is "test.txt"
Edit 2:
So I tried the way Marc provides, and I have a different problem.
I am able to create a new file, however, the content is not copied over. I tried opening the new created file in notepad and all it says is "UploadInput = test.txt"
If they simply posted the file as the body content, then there will be zero "files" involved here, so file[0] will fail. Instead, you need to look at the input-stream, and simply read from that stream. For example:
using(var file = File.Create(somePath)) {
Request.InputStream.CopyTo(file);
}

Unique File Renaming Issue

I am developing an app right now that reads in data from a windows from and generates an XML file based on the input.
I am tasked with creating a new file each time the form is updated (User presses "Submit"). (so far so good)
Here is the catch: The file has to be named after a prominent field input. (If the user types '993388CX' in the text box, the app would rename the pending file 993388CX.xml).
I understand how to actually rename a file in C#, but not how to rename it based on a form's input. Do any classes/methods exist that will dynamically rename the file based on the form input?
Code:
//Reads info1 from user input on the app UI and generates XML statement
XTemp = XDoc.CreateElement("New_Info");
XTemp.InnerText = info1.Text;
Xsource.AppendChild(XTemp);
XDoc.Save(#"C:\oldfile.xml");
I need the new file to be renamed after the string in info1.Text
If the user input was "John5", the file needs renamed to john5.xml
Thank you
Either directly save it with the correct name:
XDoc.Save(String.Format("C:\\{0}.xml",info1.Text));
OR
Rename it afterwards
File.Move("c:\\oldfile.xml", String.Format("C:\\{0}.xml",info1.Text));
XDoc.Save(#"C:\" + info1.Text + ".xml");
File.Move should do what you want.

Open File In Silverlight 4 File operation not permitted

I have a Silverlight web application(4.0) with a select file open dialog, however I get this error when the user selects a file : "File operation not permitted Access to path '' is denied"
When I try to debug it then I get this security exception "Dialogs must be user-initiated."
Is there a way around this? Has anyone has tried doing this in Silverlight?
Here is my code so far which hasn't worked:
OpenFileDialog dlg = new OpenFileDialog
{
Multiselect = false,
Filter = "All files|*.*"
};
bool? userClickedOK = dlg.ShowDialog();
if (userClickedOK == true)
{
textBox1.Text = dlg.File.FullName;
}
Because of security related restrictions you cannot open file dialogs in Silverlight directly. You can only open dialogs from inside an event handler like mouse click.
In silverlight 4, you cannot acces the FullName property, this is the cause of exception: "File operation not permitted Access to path is denied"
I trien utmost but cannot find a way to get full file path of selected file without making your application OOB.
While debugging a silverlight project, if you place a break point anywhere before the dlg.ShowDialog(), in case of your code this will raise the exception: "Dialogs must be user-initiated"
Simple way to avoid this exception is to place your break point after ShowDialog() line.
As far as I know you are not allowed to access user files if you don't have elevated permissions.
You can't get the full name of a file. And in all cases, why would you need it? There is no reason to know where the user stores her files.
If you want to read a file, use Stream property of the uploaded file instead.
I was having the same issue, after reading a lot about this problem that you cannot access dlg.File.FullName
Instead you can use this
dlg.File.Name
by doing this your exception will be removed
The error also occurs if you try to access CreationTime from a FileInfo.

User Permissions issue

I am using Visual Studio C# to parse an XML document for a file location from a local search tool I am using. Specifically I am using c# to query if the user has access to certain files and hide those to which it does not have access. I seem to have files that should return access is true however because not all files are local (IE some are web files without proper names) it is not showing access to files it should be showing access to. The error right now is caused by a url using .aspx?i=573, is there a work around or am I going to have to just remove all of these files... =/
Edit: More info...
I am using right now....
foreach (XmlNode xn in nodeList)
{
string url = xn.InnerText;
//Label1.Text = url;
try
{ using (FileStream fs = File.OpenRead(url)) { }
}
catch { i++; Label2.Text = i.ToString(); Label1.Text = url; }
}
The issue is, when it attempts to open files like the ....aspx?i=573 it puts them in the catch stack. If I attempt to open the file however the file opens just fine. (IE I have read access but because of either the file type or the append of the '?=' in the file name it tosses it into the unreadable stack.
I want everything that is readable either via url or local access to display else it will catch the error files for me.
I'm not sure exactly what you are trying to do, but if you only want the path of a URI, you can easily drop the query string portion like this:
Uri baseUri = new Uri("http://www.domain.com/");
Uri myUri = new Uri(baseUri, "home/default.aspx?i=573");
Console.WriteLine(myUri.AbsolutePath); // ie "home/default.aspx"
You cannot have ? in file names in Windows, but they are valid in URIs (that is why IE can open it, but Windows cannot).
Alternatively, you could just replace the '?' with some other character if you are converting a URL to a filename.
In fact thinking about it now, you could just check to see if your "document" was a URI or not, and if it isn't then try to open the file on the file system. Sounds like you are trying to open any and everything that is supplied, but it wouldn't hurt to performs some checks on the data.
private static bool IsLocalPath(string p)
{
return new Uri(p).IsFile;
}
This is from Check if the path input is URL or Local File it looks like exactly what you are looking for.
FileStream reads and writes local files. "?" is not valid character for local file name.
It looks like you want to open local and remote files. If it is what you are trying to do you should use approapriate metod of downloading for each type - i.e. for HTTP you WebRequest or related classes.
Note: it would be much easier to answer if you'd say: when url is "..." File.OpenRead(url) failes with exception, mesasge "...".

Categories