使用 MVC 3 以正确的方式在数据库中存储和检索文件

发布于 2024-12-09 05:53:10 字数 3431 浏览 0 评论 0原文

我有一个简单的反馈表,允许我的用户记录反馈并可选择上传与问题相关的文件。文件可以是任何格式,而不仅仅是图像。

控制器上的服务器端代码如下所示:

    [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。

将这些文件从数据库中拉回的正确方法是什么,我需要先保存到文件系统吗?文件数据是否以某种方式被损坏?如何保留原始二进制数据以使内容不受影响?

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

羁〃客ぐ 2024-12-16 05:53:10

使用 MemoryStream.ToArray() 而不是 MemoryStream.GetBuffer() -> http://msdn.microsoft.com/en-us /library/system.io.memorystream.toarray.aspx

MemoryStream.GetBuffer() 也可能返回不属于内容一部分的未使用字节。

Use MemoryStream.ToArray() instead of MemoryStream.GetBuffer() -> http://msdn.microsoft.com/en-us/library/system.io.memorystream.toarray.aspx

MemoryStream.GetBuffer() might also return unused bytes which are not part of the content.

笨笨の傻瓜 2024-12-16 05:53:10

您假设数据未正确放入数据库。

上传文件时,您应该执行以下操作:

 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)数据类型。

You're making the assumption that the data isn't put into the database incorrectly.

when uploading the file you should do something like this:

 int FileLen;
 System.IO.Stream MyStream;

 FileLen = file.ContentLength;
 byte[] input = new byte[FileLen];

 MyStream = file.InputStream;
 MyStream.Read(input, 0, FileLen);

Then assign input to your database field like this:

FileContents = input;

I'm not sure what you're using as a back end database, but if you are using 2008, use the varbinary(max) datatype.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文