I have a simple feedback form that allows my users to log feedback and optionally upload files related to the problem. The files can be of any format, not just images.
The server side code on the controller looks like this:
[HttpPost]
public ActionResult Create(Entry entry)
{
try
{
foreach (string inputTagName in Request.Files)
{
HttpPostedFileBase file = Request.Files[inputTagName];
if (file != null && file.ContentLength > 0)
{
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
db.Files.Add(new Models.File
{
Entry = entry,
FileName = Path.GetFileName(file.FileName),
FileContents = ms.GetBuffer()
});
}
}
}
entry.Status = Status.Open;
entry.Severity = Severity.Medium;
entry.DateSubmitted = DateTime.Now;
db.Entries.Add(entry);
db.SaveChanges();
return View("Complete");
}
catch
{
return View("Error");
}
}
I also have a controller action that lets me download the entire database into a zip and send it to my browser:
public ActionResult Download()
{
MemoryStream fileStream = new MemoryStream();
StringBuilder csv = new StringBuilder();
csv.AppendLine("Id,Summary,Description,Company,Name,Email,Telephone,Version,Area,Date Submitted,Notes,Resolution,Date Resolved");
using (ZipFile zip = new ZipFile())
{
foreach (Entry entry in db.Entries.ToList())
{
csv.AppendFormat("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12}",
entry.Id,
entry.Summary,
entry.Description,
entry.Company.Name,
entry.Name,
entry.Email,
entry.Telephone,
entry.Version.Number,
entry.Area,
entry.DateSubmitted,
entry.Notes,
entry.Resolution,
entry.DateResolved);
if (entry.Files.Count > 0)
{
foreach (FeedbackManager.Models.File file in entry.Files)
{
using (MemoryStream ms = new MemoryStream())
{
ms.Write(file.FileContents, 0, file.FileContents.Length);
ms.Flush();
zip.AddEntry(entry.Id+"_"+file.FileName, ms.GetBuffer());
}
}
}
}
zip.AddEntry("feedback.csv", csv.ToString());
zip.Save(fileStream);
}
return File(fileStream.GetBuffer(), "application/zip", String.Format("FeedbackToDate_{0}.zip", DateTime.Now.Date.ToShortDateString()));
}
The problem im having is reading the file data back out of the database, the zip file is getting corrupted some how and im not able to open it, if I exclude the files, I can open the zip file and I can read the csv fine.
Whats the correct way of pulling these files back out of the DB, do I need to save to the file system first? Is the file data getting corrupted some how? How do I perserve the raw binary data so the content is unaffected?
Thanks
Use
MemoryStream.ToArray()instead ofMemoryStream.GetBuffer()-> http://msdn.microsoft.com/en-us/library/system.io.memorystream.toarray.aspxMemoryStream.GetBuffer()might also return unused bytes which are not part of the content.