I am trying to read a zip file with I get via IFormFile and I am going through the files inside to unzip a selected extension and unzip it but I cannot use the IFormFile to read it. It says cannot convert IFormFile to string.
Any suggestions on how to tackle this?
using (ZipArchive archive = ZipFile.OpenRead(file))
{
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (entry.FullName.EndsWith(".dbf", StringComparison.OrdinalIgnoreCase))
{
RedirectToAction("Index");
}
}
}
Because IFormFile != string. I guess OpenRead expects a file path.
So, first read the content of the IFormFile into a file, then use that file path.
Although this won't help in this particular case (since ZipFile.OpenRead() expects a file), for those coming here after googling "iformfile to string", you can read an IFormFile into a string, for example as follows:-
var result = new StringBuilder();
using (var reader = new StreamReader(iFormFile.OpenReadStream()))
{
while (reader.Peek() >= 0)
{
result.AppendLine(reader.ReadLine());
}
}
Related
I have a web interface where users can choose one of many files from local computer and upload them to a central location, in this case Azure Blob Storage. I have a check in my C# code to validate that the filename ending is .bin. The receiving method in C# takes an array of HttpPostedFileBase.
I want to allow users to choose a zipfile instead. In my C# code, I iterate through the content of the zipfile and check each filename to verify that the ending is .bin.
However, when I iterate through the zipfile, the ContentLength of the HttpPostedFileBase object becomes 0 (zero) and when I later on upload the zipfile to Azure, it is empty.
How can I make a check for filename endings without manipulating the zipfile?
I have tried to DeepCopy a single object of HttpPostedFileBase but it is not serializable.
I've tried to make a copy of the array but nothing works. It seems that everything is reference and not value. Some example of my code as follows. Yes, I tried the lines individually.
private static bool CanUploadBatchOfFiles(HttpPostedFileBase[] files)
{
var filesCopy = new HttpPostedFileBase[files.Length];
// Neither of these lines works
Array.Copy(files, 0, filesCopy, 0, files.Length);
Array.Copy(files, filesCopy, files.Length);
files.CopyTo(filesCopy, 0);
}
This is how I iterate through the zipfile
foreach (var file in filesCopy)
{
if (file.FileName.EndsWith(".zip"))
{
using (ZipArchive zipFile = new ZipArchive(file.InputStream))
{
foreach (ZipArchiveEntry entry in zipFile.Entries)
{
if (entry.Name.EndsWith(".bin"))
{
// Some code left out
}
}
}
}
}
I solved my problem. I had to do two separate things:
First, I do not do a copy of the array. Instead, for each zip file, I just copy the stream. This made the ContentLength stay at whatever length it was.
The second thing is did was to reset the position after I looked inside the zipfile. I need to do this or else the zip file that I upload to Azure Blob Storage will be empty.
private static bool CanUploadBatchOfFiles(HttpPostedFileBase[] files)
{
foreach (var file in files)
{
if (file.FileName.EndsWith(".zip"))
{
// Part one of the solution
Stream fileCopy = new MemoryStream();
file.InputStream.CopyTo(fileCopy);
using (ZipArchive zipFile = new ZipArchive(fileCopy))
{
foreach (ZipArchiveEntry entry in zipFile.Entries)
{
// Code left out
}
}
// Part two of the solution
file.InputStream.Position = 0;
}
}
return true;
}
I am uploading a file to Api and trying to read the resource key and values. I am getting below exception when I try to read the file.
System.ArgumentException: Stream is not a valid resource file.
at System.Resources.ResourceReader._ReadResources()
at System.Resources.ResourceReader.ReadResources()
at System.Resources.ResourceReader..ctor(String fileName)
Below is the code which I tried.
[HttpPost]
public async Task<ActionResult> Post(IFormFileCollection files)
{
try
{
files = this.Request.Form.Files;
var tempFolder = Path.GetTempPath();
foreach (var formFile in files)
{
string fileName = ContentDispositionHeaderValue.Parse(formFile.ContentDisposition).FileName.Trim('"');
string filePath = Path.Combine(tempFolder, fileName);
if (formFile.Length > 0)
{
using (var stream = new FileStream(filePath, FileMode.Create))
{
await formFile.CopyToAsync(stream).ConfigureAwait(false);
}
var resReader = new ResourceReader(#filePath); // Throwing an exception.
}
}
}
catch (Exception ex)
{
throw;
}
return this.Ok("Success.");
}
Below is the request Uri and file.
Am I missing any configuration?
ResourceReader reads binary resource files (.resources) not text resource flies (.resx). At compile time the text resource files are compiled to their binary equivalent.
Refer to this link https://learn.microsoft.com/en-us/dotnet/core/extensions/work-with-resx-files-programmatically; on how to work with .resx files programmatically.
If you have the file physically and the definition of the resource in your .resx file, just rebuild your solution and the problem will be solved.
Looks like in the .NET 4.8 Framework the ResourceReader reads .resource files and the ResXResourceReader reads .resx files now.
This was different in previous versions of .Net where you could just use the ResourceReader.
To use the ResxResourceReader, add a reference to System.Windows.Forms to your project, and change the code to use the ResXResourceReader instead of the ResourceReader.
Source: https://learn.microsoft.com/en-us/dotnet/api/system.resources.resxresourcereader?view=netframework-4.8
Quick question: I need to extract zip file and have a certain file extract last.
More info: I know how to extract a zip file with c# (fw 4.5).
The problem I'm having now is that I have a zip file and inside it there is always a file name (for example) "myFlag.xml" and a few more files.
Since I need to support some old applications that listen to the folder I'm extracting to, I want to make sure that the XML file will always be extract the last.
Is there some thing like "exclude" for the zip function that can extract all but a certain file so I can do that and then extract only the file alone?
Thanks.
You could probably try a foreach loop on the ZipArchive, and exclude everything that doesn't match your parameters, then, after the loop is done, extract the last file.
Something like this:
private void TestUnzip_Foreach()
{
using (ZipArchive z = ZipFile.Open("zipfile.zip", ZipArchiveMode.Read))
{
string LastFile = "lastFileName.ext";
int curPos = 0;
int lastFilePosition = 0;
foreach (ZipArchiveEntry entry in z.Entries)
{
if (entry.Name != LastFile)
{
entry.ExtractToFile(#"C:\somewhere\" + entry.FullName);
}
else
{
lastFilePosition = curPos;
}
curPos++;
}
z.Entries[lastFilePosition].ExtractToFile(#"C:\somewhere_else\" + LastFile);
}
}
I am uploading a file into a controller using the following -
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
//I want to put file contents into a string or List<string>
}
}
I would like to either put the contents of the file into a string then loop through the string which will be a delimited list,
or
loop through the incoming stream itself, creating a list of strings out of it.
I can't figure out how to do either. I assume I would use file.InputStream in some manner?
Any help would be appreciated. Thanks!
Try using StreamReader, something like this:
string s = (new StreamReader(file.InputStream)).ReadToEnd();
string[] ss = s.Split(","); // replace "," with your separator;
I have a .lst file that has the paths of various data that has to be zipped. The path may be a direct path to an executable or a path to a log file or may contain a wildcard like - c:\abc*.exe. How do I zip all of them into a single zip file? Thanks
DotNetZip Library is #:http://dotnetzip.codeplex.com/wikipage?title=CS-examples&referringTitle=Examples
Contents of .lst file :
c:\log\abc.log
c:\log\def.log
c:\ping*.bat
c:\ping*.exe
This is what I tried:
using (ZipFile zip = new ZipFile())
{
StreamReader file = File.OpenText("C:\\pingman\\pingzipA.lst");
string read = String.Empty;
while ((read = file.ReadLine()) != null)
{
zip.AddSelectedFiles(read, true);
zip.Save("c:\\update.zip");
}
file.Close();
}
Try something like:
while ((read = file.ReadLine()) != null)
{
if (read.Contains("*"))
{
zip.AddSelectedFiles(read, true);
}
else
{
zip.AddFile(read);
}
}
zip.Save("c:\\update.zip");
Here is a link that has a TON of Examples take a look as use the examples to work for what you are trying to do.. there is even an example that uses Wild-Cards
DontNetZip Library Site with Examples
Got it to work.
if (read.Contains("*"))
{
int i = read.IndexOf("*");
string path = read.Substring(0, i--);
string doc = read.Substring(i+1);
zip.AddSelectedFiles(doc, #path, true);
}
else
{
zip.AddFile(read);
}