FileUpload does not let me to save - c#

I have a confusing problem. I'm trying to use FileUpload. The following code works well locally:
var postedFile = uploader.PostedFile;
var fileName = Path.GetFileName(postedFile.FileName);
var extension = Path.GetExtension(fileName);
var newFile = Guid.NewGuid() + extension;
var imageFilePath = Path.Combine(this.Server.MapPath("~/ProductImages"), newFile);
uploader.SaveAs(imageFilePath);
But when I publish my code to my server in internet the following exception occurs:
Could not find a part of the path [...]
When I change uploader.SaveAs(imageFilePath); to uploader.SaveAs(imageFilePath.Replace(this.Request.ServerVariables["APPL_PHYSICAL_PATH"], "..\\"));, this exception occurs:
The SaveAs method is configured to require a rooted path, and the path [..] is not rooted.
Would any one tell me how to use an Uploader? And how I can solve this problem?
With thanks

There is no problem in your code. When you run an application over the a web server, web server manged by a user in OS.(for examle nobody for enginx or Application Pool group in IIS).
You should set permission for folder that you want save the data. this my be done in your hosting file manager panel or via direct access to OS.

The problem is that local accounts aren't valid on remote resources on active directory - you need to connect as ComputerName$ or Anonymous depending on the type of local identity that you are using.
I was able to upload on debug mode but not on published site, so that might help you Mohammad.

Are you sure the folder ProductImages exists on the server?
You can try to call
Directory.CreateDirectory(this.Server.MapPath("~/ProductImages"))
before saving the file. It will create the directory if it doesn't exists or do nothing if it exists.

I finally solved the problem by setting the permission on the folder. I set the write permission on "Application pool group" for that folder and now I can upload any file there, by my app.
Thanks

Try this one.. for uploading and insert the values in database..
string filename = Path.GetFileName(FileUpload1.PostedFile.FileName);
FileUpload1.SaveAs(Server.MapPath("~/" + filename));
Stream str = FileUpload1.PostedFile.InputStream;
con.Open();
SqlCommand cmds = new SqlCommand("insert into datas(name,path,types,pricing)values(#name,#path,#types,#pricing)", con);
cmds.Parameters.AddWithValue("#name",d);
cmds.Parameters.AddWithValue("#path", filename);
cmds.Parameters.AddWithValue("#types", RadioButton1.Text);
cmds.Parameters.AddWithValue("#pricing", "FineGrained");
cmds.ExecuteNonQuery();
Response.Write("<script>alert('successfully uploaded');</script>");

Related

Why are permissions wonky when my IIS worker saves a file in ASP.NET?

IIS 8, ASP.NET MVC 4, .NET 4.5
private static string SaveProfilePicFile(UserProfileViewModel model)
{
var tempFilename = Path.GetTempFileName();
model.ProfilePic.Profile.UploadedFile.SaveAs(tempFilename);
var staticContentFilename = Helpers.GetStaticContentFilename(
StaticContentType.Avatar, model.ProfilePic.Profile.UserId);
var destinationFilename = Path.Combine(
ConfigurationManager.AppSettings["StaticContentPath"],
"profile",
staticContentFilename);
if (File.Exists(destinationFilename))
File.Delete(destinationFilename);
if (!HasJpegHeader(tempFilename)) // convert temp file into JPG
{
using (var image = new Bitmap(tempFilename))
image.Save(destinationFilename, ImageFormat.Jpeg);
File.Delete(tempFilename);
}
else
{
File.Move(tempFilename, destinationFilename);
}
return staticContentFilename;
}
I'm not interested in a code review, I know things could be done better. Right now I've hit an unusual problem. StaticContentPath points to c:\inetpub\wwwroot\static.domain.com, which is being served by a different application pool which is configured to disable scripting and cache things heavier. If I manually place a file in the static content folder, it will serve correctly. If the above code (from a different application pool) saves a file there, the permissions are very unusual. I'll attach screenshots.
The "default" file is one I pasted manually. It properly inherited permissions from the parent folder. The hashed filename was saved by the above code, and it does not inherit permissions properly. When I attempt to access the file, I get a very basic error message from IIS, the entirety of which is "The page cannot be displayed because an internal server error has occurred." No styling, nothing I'm used to seeing with IIS errors. If I manually add read permissions to the IIS_IUSRS account everything works as I'd expect.
Why is this happening, what can I do to mitigate it, and does my code need to be updated?
I suspect the problem is with the use of Path.GetTempFileName followed by File.Move. When the uploaded file is saved to tempFilename, the temporary file gets whatever permissions are assigned to the temporary folder. Moving the file preserves those permissions as is instead of recalculating the inheritable permissions based on the destination.
Instead of File.Move, try using File.Copy followed by File.Delete:
//File.Move(tempFilename, destinationFilename);
File.Copy(tempFilename, destinationFilename);
File.Delete(tempFilename);

FiIeInfo.CreationTime. How to read correct value?

I have file upload control on .aspx page, I want to upload an image at a time whose location is not always the same, could be in same directory as .sln, on desktop, anywhere.
I am using this code to read the file creation time
string savePath = MapPath("~/" + Path.GetFileName(e.FileName));
FileInfo MyFileInfo = new FileInfo(savePath);
string dt = MyFileInfo.CreationTime.Day.ToString();
string mn = MyFileInfo.CreationTime.Month.ToString();
string yr = MyFileInfo.CreationTime.Year.ToString();
I have noticed one thing that
If the image is in the same folder as the website, it gives me correct values for all
dt , mn and yr
But if it's outside that location, it always gives me same value everytime
{01/01/1601 00:00:00}
Not sure how to sort this out?
any advice, helpful code? thanks
It seems you do not understand the client/server barrier yet. Paths from the client are not meaningful on the server.
It so happens that your website is running on the same machine as the client because you are debugging locally. That is just a coincidence and it allows your code to sometimes work (by coincidence).
Proper file uploading works by ignoring the path and reading from the stream provided by the file upload control. A file upload is just a stream of bytes to the server.

Server.MapPath Could not find a part of the path in ASP.net MVC

I have the slide show that get the images in my local folder to display in my Site.Master page.
So I used :
FileInfo[] files = new DirectoryInfo(Server.MapPath("~" + "/path/blahblah/")).GetFiles();
It works fine for me when I run the project in the local, but now I changed my project throw the port http://195.155.10.521:8081, then it had one error Could not find a part of the path 'D:\path\blahblah\'.
Thanks for any help anyone can give me!
The port number on which the site is hosted doesn't really matter for the Server.MapPath method. So try splitting the method calls in order to more easily identify the problem:
var path = Server.MapPath("~/path/blahblah/");
var di = new DirectoryInfo(path);
var files = di.GetFiles();
If the error message you are getting is Could not find a part of the path 'D:\path\blahblah\' then this probably means that the D:\path\blahblah\ folder doesn't exist on your server.
var path = Server.MapPath("~/Reproting/Cashstatement.pdf");
byte[] FileBytes = System.IO.File.ReadAllBytes(path);
return File(FileBytes, "application/pdf");

ASP.NET MVC Website Read File from Disk Problem

I'm reading a text file containing an insert statement for SQL using C# in an MVC Website I'm working on. When debugging the function I'm using works fine and the insert occurs. But once I publish the site and run it on my local machine (with IIS set-up to use asp.net 4.0 even) it doesn't seem to work.
if (Request.Files != null && Request.Files["txtImportFile"] != null)
{
//newFilePath = Server.MapPath("\\" + DateTime.Now.Ticks + Request.Files["txtImportFile"].FileName);
string[] temp_string = Request.Files["txtImportFile"].FileName.Split(new char[] { '\\' });
string temp_filename = temp_string[temp_string.Count() - 1];
//newFilePath = Server.MapPath("\\temp\\" + DateTime.Now.Ticks + Request.Files["txtImportFile"].FileName);
newFilePath = Server.MapPath("\\temp\\" + DateTime.Now.Ticks + temp_filename);
Request.Files["txtImportFile"].SaveAs(newFilePath);
StreamReader reader = new StreamReader(newFilePath);
string contents = reader.ReadToEnd();
reader.Close();
Models.WingsRemoteDbLibrary dbLib = new Models.WingsRemoteDbLibrary();
string update_message = dbLib.UpdateSlaveItemsTable(contents);
if (System.IO.File.Exists(newFilePath))
System.IO.File.Delete(newFilePath);
RandomPopupView(update_message);
}
I hope my explanation doesn't sound vague. I'll try my best to answer any further questions. Thanks.
Workaround:
Instead of using
Server.MapPath("\\temp\\"...
Create folder under root with name "temp" and use
System.Web.HttpContext.Current.Request.MapPath("~\\temp....
Well, "it doesn't seem to work" is pretty vague - a bit more detail would be nice! But it sounds like a permissions issue. The default profile in IIS has very little access to the disk, especially write access. It isn't really a good idea to write inside your own site anyway (I'd use an unrelated part of the disk, myself), but you will need to configure IIS to run the application in a specific named identity, with access to the disk. Configuring the account itself (not IIS - the account; for example granting "logon as a service") to run as an ASP.NET account is not particularly trivial, unfortunately.
Another thought: is your app a sub-application, i.e. is your app-root /, or is it /MyApp/ ? The reason I ask is your use of MapPath might be better expressed relative to the app-root, i.e. ~/temp/ - but again I stress; writing inside the app is risky. You really want that folder to be non-executing.
There may be an alternative solution to this problem. You can avoid messing with path and file system altogether if you can 'bake' the file into assembly at build time. Here is how you can do this:
In Visual Studio solution explorer right click on a file and go to Properties.
Set Build Action to 'Embedded Resource'.
Later you can read the file using GetManifestResourceStream:
var stream = GetType()
.Assembly
.GetManifestResourceStream("YourNameSpace.Folder.YourFile.txt");
using (var reader = new StreamReader(stream)) {
var fileContent = reader.ReadToEnd();
}
More info here.

The SaveAs method is configured to require a rooted path, and the path <blah> is not rooted

OK I've seen a few people with this issue - but I'm already using a file path, not a relative path. My code works fine on my PC, but when another developer goes to upload an image they get this error. I thought it was a security permission thing on the folder - but the system account has full access to the folder (though I get confused about how to test which account the application is running under). Also usually running locally doesn't often give you too many security issues :)
A code snippet:
Guid fileIdentifier = Guid.NewGuid();
CurrentUserInfo currentUser = CMSContext.CurrentUser;
string identifier = currentUser.UserName.Replace(" ", "") + "_" + fileIdentifier.ToString();
string fileName1 = System.IO.Path.GetFileName(fileUpload.PostedFile.FileName);
string Name = System.IO.Path.GetFileNameWithoutExtension(fileName1);
string renamedFile = fileName1.Replace(Name, identifier);
string path = ConfigurationManager.AppSettings["MemberPhotoRepository"];
String filenameToWriteTo = path + currentUser.UserName.Replace(" ", "") + fileName1;
fileUpload.PostedFile.SaveAs(filenameToWriteTo);
Where my config settings value is:
Again this works fine on my PC! (And I checked the other person has the folder on their PC).
Any suggestions would be appreciated - thanks :)
Obviously what it says is that your filenameToWriteTo is not a rooted path... ie it is a relative path, and your server configuration doesn't like that. Use Server.MapPath to obtain real paths... something like...
string realPhysicalPath = Path.Combine(Server.MapPath(" "), filenameToWriteTo);
fileUpload.PostedFile.SaveAs(realPhysicalPath);
Just in case print out your filenameToWriteTo to see if its relative or physical path. If it's relative use the approach above.
Not sure what the issue was as it sorted itself out. We didn't end up debugging it as it was on a non developer's PC and I had a workaround for him to continue his work whilst I investigated potential causes. So maybe was the way he updated/ran the site or file permissions fixed by grabbing a copy of my directory.
At least I know it needs physical file paths so hopefully won't come across this again!
Please, make sure that folder where you are saving the file exists. If folder does not exist, it will not be created for you and SaveAs method will throw exception you are having now.
Thank you.

Categories