How to find filebytes of individual uploaded files in asp.net? - asp.net

I am implementing the multiple file upload through asp.net fileupload control & saving uploaded files to database. While iterating the files, I am trying to set the Data property of File class. For single file, I can set it as File.Data = postedFile.FileBytes.
But, while iterating files, FileBytes property value getting set everytime similar.
Can anybody explain what could be the reason? How can I implement it?
code sample:
if (fuAttachment.HasFiles)
{
foreach (HttpPostedFile postedFile in fuAttachment.PostedFiles)
{
DataAccess.File file = new DataAccess.File();
file.Data = fuAttachment.FileBytes;//not working for multiple files.
}
}

Remember, a file upload control still posts files behind the scenes.
here is basically how to retrieve multiple files, this works with one and/or multiple file upload controls, and counts ALL the posted files in ALL of the upload controls:
HttpFileCollection uploadedFiles = Request.Files;
for (int i = 0; i < uploadedFiles.Count; i++)
{
HttpPostedFile userPostedFile = uploadedFiles[i];
try
{
if (userPostedFile.ContentLength > 0)
{
//do stuff with your file, check the attributes and functions of 'userPostedFile' to see what you can get from it, there is an input stream as well as file name among everything else.
}
}
catch (Exception Ex)
{
//here do stuff if file upload fails, adjust exception type as needed.
}
}

Related

provider.FileData null in ReadAsMultipartAsync with media files

I am uploading files by using HTML File Upload control and passing data to ASP.NET Web API. Everything is working fine when I upload image or any text file or xml file. but it's giving error while I upload media files (mp3, mp4).
My code is,
string path = "//My path";
MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(path);
var task = Request.Content.ReadAsMultipartAsync(provider);
return await task.ContinueWith<bool>(t =>
{
string originalSavedAt = "";
foreach (MultipartFileData file in provider.FileData)
{
originalSavedAt = file.LocalFileName;
}
return true;
}, TaskScheduler.FromCurrentSynchronizationContext());
In above code, When I upload image file, it show me values in provider. FileData (provider.FileData.count is 1) in foreach loop.
But it is null (provider.FileData.count is 0) when I upload media file.
Status is failure in task lembda expression during media file upload, but status is RanToCompletion during image upload.
Do I need to add anything for media files. ?

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.

FileUpload control in asp.net throwing exception

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.

Using fileupload in listview edittemplate asp.net

In a ListView edittemplate, I need to allow the user to replace an image. When the form is submitted for updating how can I determine if the user is uploading a new image and get that file info?
Thanks,
James
You could try something like this if you want to compare file size. Granted file size comparison is not the best but FileInfo has lots of other attributes you should be able to use to make sure.
FileInfo oldFileInfo; // get old file's fileInfo
var tempPath = "some-temp-path-";
var tempFile = String.Format("{0}\{1}", tempPath, FileUpload1.FileName);
FileUpload1.SaveAs(tempFile);
FileInfo tempFileInfo = new FileInfo(tempFile);
if(tempFileInfo.Length == oldFileInfo.Length)
{
// ask to upload a different image
}
else
{
// do other stuff
}
Grab the name off of the FileUpload.PostedFile.

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