How to clone a HttpPostedFile - c#

I have an application that allows a user to upload a file, the file is scanned with Symantec protection engine before it is saved. The problem I'm encountering is that after the files are scanned with protection engine they have 0 bytes. I'm trying to come up with a solution to this problem.
I've tried the cloning solution mentioned here: Deep cloning objects, but my uploaded files are not all Serializable. I've also tried resetting the stream to 0 in the scan engine class before passing it back to be saved.
I have been in contact with Symantec and they said the custom connection class that was written for this application looks correct, and protection engine is not throwing errors.
I'm open to any solution to this problem.
Here is the code where the file is uploaded:
private void UploadFiles()
{
System.Web.HttpPostedFile objFile;
string strFilename = string.Empty;
if (FileUpload1.HasFile)
{
objFile = FileUpload1.PostedFile;
strFilename = FileUpload1.FileName;
if (GetUploadedFilesCount() < 8)
{
if (IsDuplicateFileName(Path.GetFileName(objFile.FileName)) == false)
{
if (ValidateUploadedFiles(FileUpload1.PostedFile) == true)
{
//stores full path of folder
string strFileLocation = CreateFolder();
//Just to know the uploading folder
mTransactionInfo.FileLocation = strFileLocation.Split('\\').Last();
if (ScanUploadedFile(objFile) == true)
{
SaveFile(objFile, strFileLocation);
}
else
{
lblErrorMessage.Visible = true;
if (mFileStatus != null)
{ lblErrorMessage.Text = mFileStatus.ToString(); }
I can provide the connection class code if anyone needs that, but it is quite large.

You could take a copy of the filestream before you pass it into the scanning engine.
byte[] fileData = null;
using (var binaryReader = new BinaryReader(Request.Files[0].InputStream))
{
fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength);
}
// pass the scanning engine
StreamScanRequest scan = requestManagerObj.CreateStreamScanRequest(Policy.DEFAULT);
//...
Update
To copy the stream you can do this:
MemoryStream ms = new MemoryStream();
file.InputStream.CopyTo(ms);
file.InputStream.Position = ms.Position = 0;

Related

.NET 7 System.IO.FileNotFoundException: Could not find file

This is my first time asking around here, so sorry if it's not worded very well.
I have a blazor WebAssembly project with MudBlazor, and when I try to upload files to save them into a database, it appears the next error message in the browser console.
System.IO.FileNotFoundException: Could not find file
When the user uploads the files I call the next method to save the files into IList<IBrowserFile>.
IList<IBrowserFile> Files = new List<IBrowserFile>();
private void OnInputFileChanged(InputFileChangeEventArgs e)
{
var files = e.GetMultipleFiles();
foreach(var file in files)
{
Files.Add(file);
}
}
Once the user has uploaded all the files, they click on a button that call the next method to upload it into a database.
[Inject] protected ISnackbar Snackbar { get; set; } = default!;
private async void Upload()
{
List<string>? notUploadFiles = null;
foreach(var file in Files)
{
byte[] fileBytes = File.ReadAllBytes(destPath + file.Name);
string extn = new FileInfo(file.Name).Extension;
var addArchivoTarea = new AddArchivoTareaRequestDTO(Tarea.Id, fileBytes, extn);
var successResponse = await HttpTareas.AddArchivoToTareaAsync(addArchivoTarea);
if (!successResponse)
{
notUploadFiles.Add(file.Name);
}
}
if(notUploadFiles is not null) {
Snackbar.Configuration.SnackbarVariant = Variant.Filled;
Snackbar.Add("The following files could not be uploaded:", Severity.Info);
Snackbar.Configuration.SnackbarVariant = Variant.Outlined;
foreach (var file in notUploadFiles)
{
Snackbar.Add(file, Severity.Error);
}
//Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter;
//Snackbar.Add("TODO: Upload your files!", Severity.Normal);
MudDialog.Close(DialogResult.Ok(true));
}
Snackbar.Add("All files have been successfully uploaded", Severity.Success);
MudDialog.Close(DialogResult.Ok(true));
}
I don't know where is the problem, any idea?
The uploaded files are not in the file system, they are in-memory only. The way to access the raw data would be something like:
byte[] fileBytes;
using (Stream s = file.OpenReadStream())
{
MemoryStream ms = new MemoryStream();
await s.CopyToAsync(ms);
fileBytes= ms.ToArray();
}

I read pdf file then for show on the client I use tempStream.WriteByte but it reverse writing

By the way my english not perfect sory .
I use this method . I want to read file then show of pdf format on the client. So this code can do it.
But when I show pdf file . İt did reverse write on the document. What is my problem I cant understand
FileStream fileStream = File.OpenRead(fileDirectoryPath + "\\" + pROJEDOKUMANBec.FILENAME);
pROJEDOKUMANBec.SOURCE = ConvertStreamToByteBuffer(fileStream);
public byte[] ConvertStreamToByteBuffer(System.IO.Stream theStream)
{
int b1;
System.IO.MemoryStream tempStream = new System.IO.MemoryStream();
while ((b1 = theStream.ReadByte()) != -1)
{
tempStream.WriteByte(((byte)b1));
}
return tempStream.ToArray();
}
And here my ts code.
#ViewChild('pdfViewir') pdfViewir: PdfViewer;
private _openPdf(bec: ProjeDokumanBec): void {
this._rptSrc = bec.SOURCE;
this.pdfViewir.Zoom = 1;
this.pdfViewir.OriginalSize = true;
}
here my html code
<PdfViewer #pdfViewir Id="pdfViewir" [Src]="_rptSrc"></PdfViewer>

zip file giving me the archive entry was compressed using an unsupported compression method

I have a to create a routine that will unzip multiple zip files( average size of the zip will be 2GB) in parallel. So, I created a function that using TPL to unzip the files.
This works well in principle. I don't have test data yet so i figured I would make a copy of the zip file that currently exists and rename the files in it and rezip it. Well, I am getting the following error when I do that:
the archive entry was compressed using an unsupported compression method
Well please comment on the code as you see fit and why am I getting the error here.
Code:
private static void UnzipfilesInTemp()
{
Task[] unzippers = null;
bool rtn = false;
//--UNZIP FILES IN TEMPORARY LOCATION
var TEMP_ZIP_FILES = System.IO.Directory.GetFiles(tempPath, "*" + Statement*.zip");
unzippers = new Task[TEMP_ZIP_FILES.Length];
unZippedFiles = new string[TEMP_ZIP_FILES.Length];
lock (thisLock)
{
for (int i = 0; i <= TEMP_ZIP_FILES.Length - 1; i++)
{
string filename = TEMP_ZIP_FILES[i];
unzippers[i] = Task.Factory.StartNew(() =>
{
//--UNZIP FILE FOR STATEMENT IMPORTING
try
{
ZipFile.ExtractToDirectory(filename, tempPath);
}
catch (Exception)
{
//--UNABLE TO UNZIP FILES
_coreprocess.AddLogDetailRecord(MSG, false, "");
ProcessSuccess = false;
ExitAllCode();
}
});
}
}
Task.WaitAll(unzippers);
unZippedFiles = System.IO.Directory.GetFiles(tempPath, "*" + BANK_NUM + "*.PDF");
}

Need to open and save Excel file before reading it

I have a method were I create an Excelsheet. When the file is created I need to open it and save it manually in Excel before I can read it with Excel Data Reader. If I open and save the exact same file without changeing anything I can read it like I wan't it to work. Does anyone know how I can:
a) Save it properly when creating the file (using EPPlus)?
or
b) Open the already created file and save it properly by using C# before I try to read it?
My create method:
public void CreateAnnuityExcelSheet(List<Calculation> cList, FormCollection form, int DTCyear)
{
string fileName = "test";
string path = #"C:\ExcelFiles\" + fileName + ".xlsx"; //Path for the file
FileInfo info = new FileInfo(path);
info.Directory.Create(); //If C:\ExcelFiles does not exist, create it
if (!info.Exists)
{
using (ExcelPackage package = new ExcelPackage(info))
{
ExcelWorksheet ws = package.Workbook.Worksheets.Add(fileName);
//Filling the worksheet with values here...
package.SaveAs(info);
}
}
}
My read method:
[HttpPost]
public ActionResult ShowExcelFile(GetExcel model)
{
List<Calculation> cList = new List<Calculation>();
DataSet result = null;
var file = model.Files[0];
if (file != null && file.ContentLength > 0)
{
// .xlsx
IExcelDataReader reader = ExcelReaderFactory.CreateOpenXmlReader(file.InputStream);
reader.IsFirstRowAsColumnNames = true;
result = reader.AsDataSet();
reader.Close();
var PV = Convert.ToDecimal(data.Table.Rows[1][6]); //Works fine if the file is opened and saved in Excel. Else null..
//Work with the dataset here. When the file is not opened and saved it gets null everywhere. Else it works fine
}
return View("ShowExcelFile", model);
}
I have also tried using WriteAllBytes instead of using package.SaveAs():
byte[] data = package.GetAsByteArray();
System.IO.File.WriteAllBytes(path, data);
This gets my the exact same result. I still need to open and save the file manually.

C# Saving an MP4 Resource to a file

I've tried a few different ways but it won't open when it's saved. How can I accomplish this?
Basically I want to be able to save an MP4 file that's currently a resource file to a temp location that I can access as a path.
Here's something I've tried:
public static void WriteResourceToFile(string resourceName, string fileName)
{
using (Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
{
if (s != null)
{
byte[] buffer = new byte[s.Length];
char[] sb = new char[s.Length];
s.Read(buffer, 0, (int)(s.Length));
/* convert the byte into ASCII text */
for (int i = 0; i <= buffer.Length - 1; i++)
{
sb[i] = (char)buffer[i];
}
using (StreamWriter sw = new StreamWriter(fileName))
{
sw.Write(sb);
sw.Flush();
}
}
}}
You're overcomplicating it.
Try something like this (note, not compiled or tested, and Stream.CopyTo() only exists in .NET 4.0 and later).
using (Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)))
using (FileStream fs = File.Open("c:\myfile.mp4", FileMode.Create))
{
s.CopyTo(fs);
}
Job done.
If you don't have .NET 4.0 available, you'll need to implement one yourself, like one of these: How do I copy the contents of one stream to another?
To get a list of all of the resource names in the current assembly, do something like this:
Assembly a = Assembly.GetExecutingAssembly();
foreach (string s in a.GetManifestResourceNames())
{
Console.WriteLine(s);
}
Console.ReadKey();
Take what turns up on the console and pass it into GetManifestResourceStream() in the first snippet I posted.
http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getmanifestresourcenames.aspx
Why are you writing an MP4 as a string? You should write out bytes without modification. Your conversion to chars is modifying the data. Use The FileStream call and call the Write method.
you could try something like this:
I pasted the wrong code in.... sorry, i was in a hurry
[HttpPost]
public ActionResult Create(VideoSermons video, HttpPostedFileBase videoFile)
{
var videoDb = new VideoSermonDb();
try
{
video.Path = Path.GetFileName(videoFile.FileName);
video.UserId = HttpContext.User.Identity.Name;
videoDb.Create(video);
if (videoFile != null && videoFile.ContentLength > 0)
{
var videoName = Path.GetFileName(videoFile.FileName);
var videoPath = Path.Combine(Server.MapPath("~/Videos/"),
System.IO.Path.GetFileName(videoFile.FileName));
videoFile.SaveAs(videoPath);
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
this actually loads video files to a directory, but it should work for your format as well.
-Thanks,

Categories