get FileInfo for HttpPostedFileBase - c#

Is there a simple way to get the FileInfo object from an HttpPostedFileBase? I realize I can save the file then do something like DirectoryInfo.GetFiles and then loop through the files looking for my file, but is there any simpler way to do this for a given file?

There's no FileInfo associated to an uploaded file. Only the filename is sent as parameter as well as the file stream itself. So that's what you could query:
HttpPostedFileBase file = ...
string filename = file.FileName;
int fileSize = file.ContentLength;
string contentType = file.ContentType;
using (Stream stream = file.InputStream)
{
// do something with the file contents here
}
To better understand what gets sent from the client I invite you to read the multipart/form-data specification.
The FileInfo object contains things like LastModified and LastAccessed date which is not an information that is sent when a file is uploaded. If you save the file on your web server disk and then retrieve the FileInfo from it bear in mind that what you will be retrieving is the information about this file on the server and not on the client simply because this information is never sent when a file is uploaded.

Related

How can I get file from filepath in ASP.NET and return the file to the client

I am very new in ASP.NET. I want help about how to get file from specific location and send to the client through action controller.
To send any file to the client from the server I can use..............
var fileBytes = System.IO.File.ReadAllBytes(inkFormulation.DocumentPath);
var ext = ImageFormat.Jpeg;// the file extension you want to use
return base.File(fileBytes, $"image/{ext}", $"SampleImage.{ext}");
This is for image file. You can send any file with specific file extension.

C# - Extracting contents of compressed file without saving

I have a compressed file (.osz) stored on an S3 Bucket which contains a .os file which I need to read the contents of.
I need to be able to extract/decompress and read the contents of the compressed file without downloading the file directly to the PC due to security reasons.
I am able to retrieve the compressed file (.osz) using the URL address of it's S3 Bucket path. Then using ZipArchive I am able to access the files contained within the compressed file. I am then able to extract the file I require by using the 'ExtractToFile' function as seen below. However, this function extracts the file (.os) and saves it locally in the path specified.
WebClient client = new WebClient();
byte[] bytes = client.DownloadData(OSZFilepath); // Read the .osz file contents into a byte array
using (MemoryStream zipStream = new MemoryStream(bytes))
{
// Create the zip containing the file from the stream
ZipArchive zip = new ZipArchive(zipStream);
// extract the compressed file and download the .os file contained within
var fileName = Guid.NewGuid().ToString() + ".OS";
var baseDirectory = Environment.ExpandEnvironmentVariables(System.Web.Configuration.WebConfigurationManager.AppSettings["DataStorage"].ToString());
zip.Entries[0].ExtractToFile(Path.Combine(baseDirectory, "ProjectFiles", fileName));
Although this extracted file can be successfully read and imported by my program, I cannot use this method as I am not able to save the file onto the user's computer due to security restrictions and program requirements.
Therefore I need to programmatically extract/decompress the file I need in order to read the contents and programmatically import it into my program.
I have tried to use the following code to do this:
ZipArchiveEntry entry = zip.GetEntry(zip.Entries[0].Name);
Stream stream = entry.Open();
StreamReader reader = new StreamReader(stream);
string contents = reader.ReadToEnd();
However the resulting contents throws up an error when I try to import it, indicating that the contents is different to the contents of the file that gets saved using 'ExtractToFile'.
This is confirmed when I save this contents as a seperate file and compare it to the file saved using 'ExtractToFile'. The 'ExtractToFile' file is bigger than the latter.
So my question is: is there another way to successfully decompress/extract a compressed file and obtain the contents without using the 'ExtractToFile' method and having to save the extracted file somewhere?
Thanks for your help.

Generating a zipOutputstream from a folder having other .zip files in it

I am trying to convert an entire azure blob storage folder and its contents to a zip file .Inside this folder ,I have different types of files eg, .txt,.mp3,.zip files .But once the folder is converted to zip file I noticed that all the .zip file types got corrupted,.How can I prevent my zip files from corrupted. I am using Ionic.Zip library to generate zip files
Here is the code I am using .Here I am able to generate and download the zip file successfully with all other filetypes except the inner zip files.
var allFiles = directory.ListBlobs(new BlobRequestOptions { UseFlatBlobListing = true }).Where(x => x.GetType() == typeof(CloudBlockBlob)).Cast<CloudBlob>();
string xyzblob = directory.Uri.ToString().TrimEnd('/');
var dBlob = blobClient.GetBlobReference(xyzblob);
byte[] fileBytes = null;
fileBytes = dBlob.DownloadByteArray();
foreach (var file in allFiles)
{
using (var fileStream = new MemoryStream(fileBytes))
{
var entryName = file.Uri.ToString().Replace(directory.Uri.ToString(), "");
zipOutputStream.PutNextEntry(entryName);
fileStream.Seek(0, SeekOrigin.Begin);
int count = fileStream.Read(fileBytes, 0, fileBytes.Length);
while (count > 0)
{
zipOutputStream.Write(fileBytes, 0, count);
count = fileStream.Read(fileBytes, 0, fileBytes.Length);
if (!Response.IsClientConnected)
{
break;
}
Response.Flush();
}
fileStream.Close();
}
}
zipOutputStream.Close();
More details
I am downloading a folder ,."myFolder" and its contents from azure blob as a zip file eg, myfolders.zip.
Here is how the file structure inside "myFolder" /azure blob
MyFolder/mymusic/ test.mp3
MyFolder/mytext/ newtext.txt
MyFolder/MyZipfiles/ myzip.zip
My code I posted above will generate a zip all the contents of the folder to create "MyFolder.zip" and will download automatically .Now if you unzip "MyFolder.zip" file , due to some reason , the myzip.zip is getting corrupted.If I try to open myzip.zip file ,its showing a message "windows cannot open the folder ,the compressed zipped folder "myzip.zip" is invalid"
Please help me find a solution so that the .zip files wont get corrupted
I tried to download to stream ,but same results.,The inner zip files are getting corrupted.all other file types are in good shape.
zipOutputStream.PutNextEntry(entryName);
destBlob.DownloadToStream(zipOutputStream);
I am assuming you already tried downloading one of those zip files and opening it, right?
If that is the case, one thing I would suggest is to eliminate the intermediate fileBytes array completely. Using fileBytes as the buffer to fileStream and then reading from fileStream to fileBytes might be the culprit. On the other hand, you start from offset 0 and write to the beginning of fileBytes anyway, so it might be working just fine.
In any case, a more efficient solution is; you can call PutNextEntry and then call the blob object's DownloadToStream method by passing in the zip stream itself. That would simply copy the entire blob directly into the zip stream without having to manage an intermediate buffer.
When it starts to pick the .zip file ,I added BlobReference to .zip file and this resolved the issue
dBlob = blobClient.GetBlobReference(entryName.EndsWith(".zip") ? file.Uri.ToString() : xyzblob);
zipOutputStream.PutNextEntry(entryName);
dBlob.DownloadToStream(zipOutputStream);

handling an uploaded file via FileStream

I am allowing the user to upload a file(doc, pdf, excel, txt) and then i am passing in FileStream to read and then write but after opening it i am calling a stored procedure so i can store the file name, date, upload user and where i will be a copy of it. My problem is how can deal with the string filename that has been pased in the FileStream and the stored procedure wants a string filename.
string docx = #"../../TestFiles/Test.docx";
try
{
FileStream fileStream = new FileStream(docx, FileMode.Open, FileAccess.Read);
docConverter.UpLoadFile(11, "Test.docx", "../../TestFiles/", 1, "../../Temp/", 89);
}
public void UpLoadFile(int studentId, string rawStoragePath, int uploadedByUserId, string storagePath, int assignmentElementsId)
{
Guid strGUID = Guid.NewGuid();
DateTime uploadDate = DateTime.UtcNow;
//calling stored procedure
stuSubSvc.UploadWork(studentId, strGUID, (need to pass file name), rawStoragePath, uploadDate, uploadedByUserId, storagePath, 0, assignmentElementsId);
}
Help with:
1 - getting file name from file in FileStream
2 - getting path of the uploaded file from FileStream
To get the filename out of full path you can use:
Path.GetFileName(".././Test.docx")
It'll give you Test.docx
you can't get the path of the file on the client machine. The FileStrame has a property called Handle that contains the native handle of the opened file, you follow the following article it will help you to get the file name by the handle, it is in C++ but the all functions are APIs can be called using P/Invoke in C# [DllImport].
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366789(v=vs.85).aspx
Edit
Sorry the Handle is obsolete use SafeFileHandle instead
1 - getting file name from file in FileStream
There's no filename in a stream. You can get the filename of the uploaded file from the HttpPostedFileBase instance that your controller action receives as parameter. Take a look at Phil Haack's blog post about uploading files in an ASP.NET MVC application in which he illustrates that.
Assuming you have already stored the file on your file system, you could retrieve the filename from the Name property of the FileStream:
string filename = Path.GetFileName(fileStream.Name);
2 - getting path of the uploaded file from FileStream
There's no filename nor filepath in a stream. All you can hope of getting is the filename which is contained in the HttpPostedFileBase instance that your controller action should receive as parameter (see previous point).

Upload zip file error

I am using Uploadify to upload multiple files in my ASP.NET MVC application. In the controller action, I need to check if one of the uploaded files is a zip file, and if yes, I need to check its contents. For the zip functionality I am using the ICSharpCode.SharpZipLib.
When uploading a zip file from say my desktop, I am getting the following error:
Could not find file 'C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0\xyz.zip' on the following line of code:
FileStream fs = System.IO.File.OpenRead(Path.GetFullPath(fileData.FileName));
ZipFile zf = new ZipFile(fs);
How do I get past this error?
[HttpPost]
public ActionResult Upload(HttpPostedFileBase fileData)
{
if (fileData != null && fileData.ContentLength > 0)
{
if (Path.GetExtension(fileData.FileName) == ".zip")
{
FileStream fs = System.IO.File.OpenRead(Path.GetFullPath(fileData.FileName));
ZipFile zf = new ZipFile(fs);
foreach (ZipEntry zipEntry in zf)
{
}
}
else
{
var fileName = Server.MapPath("~/Content/uploads/" + Path.GetFileName(fileData.FileName));
fileData.SaveAs(fileName);
return Json(true);
}
}
return Json(false);
}
HttpPostedFileBase.FileName is the name of the file uploaded, not the location on the file stored on the server. HttpPostedFileBase does not store the file on the server, only as a stream. Your options are either open the stream in memory (if your 3rd party utilies allow for opening streams) or saving the file to a known location, then open it from that location.
Path.GetFullPath gets a full path from the current directory.
That has nothing to do with your HttpUploadedFileBase, which isn't on disk.
You need to pass a stream instead of a file path.
If you want to check if it is a zip file, you could always look at the content-type coming back.
application/zip
This might work for what you are trying to do. Also, just try and look at what the content-type, you might find something more specific to your needs.

Categories

Resources