FileUpload control in asp.net throwing exception - asp.net

I am trying to read an Excel sheet using C# which is to be loaded by end user from fileUpload control.
I am writing my code to save the file on server in event handler of another button control(Upload). But when I click on Upload Button I am getting this exception:
The process cannot access the file 'E:\MyProjectName\App_Data\sampledata.xlsx' because it is being used by another process.
Here is the code that I have used in event handler:
string fileName = Path.GetFileName(file_upload.PostedFile.FileName);
string fileExtension = Path.GetExtension(file_upload.PostedFile.FileName);
string fileLocation = Server.MapPath("~/App_Data/" + fileName);
//if (File.Exists(fileLocation))
// File.Delete(fileLocation);
file_upload.SaveAs(fileLocation);
Even deleting the file is not working, throwing the same exception.

Make sure, some other process is not accessing that file.
This error might occurs whenever you are trying to upload file, without explicitly removing it from memory.
So try this:
try
{
string fileName = Path.GetFileName(file_upload.PostedFile.FileName);
string fileExtension = Path.GetExtension(file_upload.PostedFile.FileName);
string fileLocation = Server.MapPath("~/App_Data/" + fileName);
//if (File.Exists(fileLocation))
// File.Delete(fileLocation);
file_upload.SaveAs(fileLocation);
}
catch (Exception ex)
{
throw ex.Message;
}
finally
{
file_upload.PostedFile.InputStream.Flush();
file_upload.PostedFile.InputStream.Close();
file_upload.FileContent.Dispose();
//Release File from Memory after uploading
}

The references are hanging in memory, If you are using Visual Studio try with Clean Solution and Rebuild again, if you are in IIS, just do a recycle of your application.
To avoid this problems try to dispose the files once you used them, something like:
using(var file= new FileInfo(path))
{
//use the file
//it will be automatically disposed after use
}

If i have understood the scenario properly.
For Upload control, I don't think you have to write code for Upload Button. When you click on your button,your upload control has locked the file and using it so it is already used by one process. Code written for button will be another process.
Prior to this, check whether your file is not opened anywhere and pending for edit.

Related

providing feedback for file uploads

When uploading files to a server what information should be provided to the user for feedback? I have created a website that allows users to upload files to a server. I would think a progress bar would be nice or at the very least a message to let the users know that the process was successful or not. Another issue is how do I know that the operation was successful? Right now the only thing I can think of is to check if the files exist after they are saved. I am using C# .NET 2.0 on the server side. Here is an example of the code I have for saving the files...
private void fileUpload(HttpContext context)
{
string stgDir = #"myDir",
fullPath;
HttpFileCollection hfc = context.Request.Files;
for(int i = 0; i < hfc.Count; i++)
{
fullPath = Path.Combine(BASE_PATH, stgDir);
if(!Directory.Exists(fullPath))
{
Directory.CreateDirectory(fullPath);
}
if(hfc[i].ContentLength > 0)
{
fullPath = Path.Combine(fullPath,hfc[i].FileName);
hfc[i].SaveAs(fullPath);
}
}
}
If you don't get an exception is very unlikely that there was an error saving the file, so, add a try catch and show your user an error if exception is catch, or just a friendly message indicating the file was uploaded.
Regarding the info as feedback, that's up to you and what you would like the user to know, maybe success message and a link to the file would be enough.

ASP.NET Photo Upload

When uploading a photo to my server using the following code, I'm receiving an erroneous value. This is working fine in the debug mode and when published in localhost.
string filePath = Path.Combine(HttpContext.Server.MapPath("../Uploads"), date);
if (!Directory.Exists(HttpContext.Server.MapPath("../Uploads")))
{
Directory.CreateDirectory(HttpContext.Server.MapPath("../Uploads"));
}
file.SaveAs(filePath);
Can someone please point out what I've done incorrectly?
ok I am assuming that you are using File Upload control or you can use the below sample code if you want to use the FileUpload control in your asp.net page.
Add the FileUpload control (Here im adding ajax async FileUpload control and named as asyncFileUpload.
Write A Method and Call it whenever you want.
public int AsyncFileUpload()
{
string xlsFile = AsyncFileUpload1.FileName;
if (AsyncFileUpload1.HasFile)
{
string FileName = Path.GetFileName(AsyncFileUpload1.PostedFile.FileName);
string Extension = Path.GetExtension(AsyncFileUpload1.PostedFile.FileName);
string FilePath = Server.MapPath("~/Uploads/" + FileName);
if (Extension == ".doc")//check the file extension here
{
AsyncFileUpload1.SaveAs(FilePath);
}
}
}

Deleting file after upload

I am trying to upload a file with the FileUpload control. When file is uploaded, I extract information from it and then i want to delete it.
I manage to upload it, save it and get the info from it, but when i try to delete it i get the follwing exception
"The process cannot access the file 'D:\IIS**OMITTED***\V75 personal ny.csv' because it is being used by another process.
string fn = Path.GetFileName(fu.PostedFile.FileName);
string SaveLocation = Server.MapPath("UploadedCSVFiles") + "\\" + fn;
FileInfo fi = new FileInfo(SaveLocation);
fu.PostedFile.SaveAs(SaveLocation);
fu.PostedFile.InputStream.Dispose();
DataTable dt = AMethodThatUsesFile(SaveLocation);
fi.Delete();
Try this code to delete file.
System.IO.File.Delete(SaveLocation );
You specified a method AMethodThatUsesFile(SaveLocation);. If it uses any classes like StreamReader to read file, please close the reader using StreamReader.Close(); method before trying to delete
dispose the fi before deleting. and then us File.Delete(). remember to use using statements when use disposable objects, or dispose it after use.
using System.io
File.Delete(Server.MapPath("../Nurturing/" + fnevents));
FileInfo fInfoEvent;
fInfoEvent = new FileInfo(fnevents);
fInfoEvent.Delete();
here fnevents is the name of the file that u are deleting. Nurturing is the name of the folder.

c:\windows\system32\inetsrv\Test.pdf is denied

I have a requirement to generate a pdf document on a button click on using visual web part- sharepoint 2010.
I am using the the open source library http://www.itextpdf.com/ for the same. I am able to execute the below code using the project type as a Windowns Application. But, when I want do it on a button click , I am receiving c:\windows\system32\inetsrv\Test.pdf' is denied. error.
Below is the code that I am using
public static void Main(string[] args) --Console Application
{
Console.WriteLine("PDF demo");
Document myDoc = new Document(PageSize.A4.Rotate());
try
{
PdfWriter.GetInstance(myDoc, new FileStream("Salman.pdf", FileMode.Create));
myDoc.Open();
myDoc.Add(new Paragraph("First pdf File made by Salman using Itext"));
}
catch (DocumentException ex)
{
Console.Error.WriteLine(ex.Message);
}
myDoc.Close();
}
}
But I want do the same on a button click event.
protected void pdfGenerator_OnClick(object sender, EventArgs e)
{
Document myDoc = new Document(PageSize.A4.Rotate());
try
{
PdfWriter.GetInstance(myDoc, new FileStream("Salman.pdf", FileMode.Create));---I get an error here
myDoc.Open();
myDoc.Add(new Paragraph("First pdf File made by Salman using Itext"));
}
catch (DocumentException ex)
{
Console.Error.WriteLine(ex.Message);
}
myDoc.Close();
}
}
Please help me , i dont understand the reason for the error. I am tyring it for the first time.
The problem is you are trying to create a PDF in a directory you do not have access to. This is because you are not specifying the directory to save the path; which causes it to default in the same location as the current working directory. In many cases, such as for ASP.NET; the default is the same as the location of the process. For ASP.NET, the process is w3wp.exe and resides in c:\windows\system32\inetsrv. Most identities that w3wp will run as (Network Service or AppPoolIdentity) do not have access to that directory. In fact, only system administrators do.
You need to save it somewhere else that the process has write permissions to here:
PdfWriter.GetInstance(myDoc, new FileStream("Janaki.pdf", FileMode.Create))
Should be something like:
PdfWriter.GetInstance(myDoc, new FileStream(#"C:\directoryIcanWriteTo\Janaki.pdf", FileMode.Create))
If you want to save it in the same place as the website, you would use HttpContext.Current.Server.MapPath:
PdfWriter.GetInstance(myDoc, new FileStream(HttpContext.Current.Server.MapPath("~/Janaki.pdf", FileMode.Create))
Regardless, the identity will still need write permissions to the directory if it doesn't have them. But you definitely shouldn't put them in inetsrv.
Just don't use "FileStream" which requires write permissions on the server. Replace it with MemoryStream and then flush its content on the user's browser.

Uploading an XML file, referencing an XSD, in ASP.Net

I have an XML file which is being uploaded to an ASP.Net page via the normal file upload control. When it gets up, I am attempting to validate and deserialize the XML. However, the code below is really very handy for validating an XML file which references it's XSD like this:
xsi:schemaLocation="someurl ..\localSchemaPath.xsd"
However, if I upload this XML file, only the XML file gets uploaded, so ..\localSchemaPath.xsd doesn't exist, so it can't validate.
Even if I stored the XSD locally, it still wouldn't be quite right as the XML file could be written with a schema location like:
xsi:schemaLocation="someurl ..\localSchemaPath.xsd"
or
xsi:schemaLocation="someurl localSchemaPath.xsd"
or
xsi:schemaLocation="someurl ..................\localSchemaPath.xsd"
if it so wished.
Dilemma!
(For the purposes of this question, I have pinched the code below from: Validating an XML against referenced XSD in C#)
using System.Xml;
using System.Xml.Schema;
using System.IO;
public class ValidXSD
{
public static void Main()
{
// Set the validation settings.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
// Create the XmlReader object.
XmlReader reader = XmlReader.Create("inlineSchema.xml", settings);
// Parse the file.
while (reader.Read()) ;
}
// Display any warnings or errors.
private static void ValidationCallBack(object sender, ValidationEventArgs args)
{
if (args.Severity == XmlSeverityType.Warning)
Console.WriteLine("\tWarning: Matching schema not found. No validation occurred." + args.Message);
else
Console.WriteLine("\tValidation error: " + args.Message);
}
}
Here is a chunk of code I use to validate xml with a local schema:
string errors = string.Empty;
try
{
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(string.Empty, Page.MapPath("~/xml/Schema.xsd"));
XmlDocument doc = new XmlDocument();
doc.Schemas = schemas;
doc.Load(Page.MapPath("~/xml/sampleXML.xml"));
//use this line instead of the one above for a string in memory.
//doc.InnerXml = xmlToValidate;
ValidationEventHandler validator = delegate(object send, ValidationEventArgs ve)
{
errors += "\n" + ve.Severity + ": " + ve.Message;
};
doc.Validate(validator);
}
catch (XmlException xe)
{
errors += "\n" + xe.Message;
}
catch (XmlSchemaValidationException xe)
{
errors += "\n" + xe.Message;
}
I can't quite make out whether you are attempting a generic validate-against-any-referenced-schema, or if you have a specific schema that you validate against every time, and are just not sure how to handle the references.
If it's the latter, then make the schema public on the internet, and tell people to reference it by URI.
If it's the former, then I would suggest the following:
First the user uploads an XML file.
Parse the XML file for a schema reference. Tell them "References to yourSchema.xsd were found; please upload this file below" with a new upload box.
Then, validate the file against the uploaded schema. To do this, modify the Schemas property of your settings object, instead of modifying the ValidationFlags property.

Resources