我有一个简单的反馈表单,允许我的用户记录反馈,并可选择上传与问题相关的文件。文件可以是任何格式,而不仅仅是图像。
控制器上的服务器端代码如下所示:
[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");
}
}
我还有一个控制器动作,可让我将整个数据库下载到一个zip中并发送到我的浏览器:
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()));
}
问题是我正在读取数据库中的文件数据,zip文件被破坏了一些如何和我无法打开它,如果我排除文件,我可以打开zip文件,我可以读取csv罚款。
将这些文件从数据库中拉出来的正确方法是什么,我是否需要先保存到文件系统?文件数据是如何被破坏的?如何保存原始二进制数据以使内容不受影响?
由于
答案 0 :(得分:3)
使用MemoryStream.ToArray()
代替MemoryStream.GetBuffer()
- > http://msdn.microsoft.com/en-us/library/system.io.memorystream.toarray.aspx
MemoryStream.GetBuffer()
也可能返回不属于内容的未使用字节。
答案 1 :(得分:0)
您假设数据未正确放入数据库。
上传文件时,您应该执行以下操作:
int FileLen;
System.IO.Stream MyStream;
FileLen = file.ContentLength;
byte[] input = new byte[FileLen];
MyStream = file.InputStream;
MyStream.Read(input, 0, FileLen);
然后将输入分配给数据库字段,如下所示:
FileContents = input;
我不确定您使用的是什么作为后端数据库,但如果您使用的是2008,请使用varbinary(max)数据类型。