Правильное хранение и получение файлов в БД с помощью MVC 3 - PullRequest
2 голосов
/ 12 октября 2011

У меня есть простая форма обратной связи, которая позволяет моим пользователям регистрировать отзывы и при необходимости загружать файлы, связанные с проблемой. Файлы могут быть любого формата, а не только изображения.

Код на стороне сервера на контроллере выглядит так:

    [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 штраф.

Как правильно извлекать эти файлы из БД, нужно ли сначала сохранять их в файловой системе? Являются ли данные файла поврежденными как-то? Как сохранить необработанные двоичные данные, чтобы их содержимое не затрагивалось?

Спасибо

Ответы [ 2 ]

3 голосов
/ 12 октября 2011

Используйте MemoryStream.ToArray() вместо MemoryStream.GetBuffer() -> http://msdn.microsoft.com/en-us/library/system.io.memorystream.toarray.aspx

MemoryStream.GetBuffer() также может возвращать неиспользованные байты, которые не являются частью содержимого.

0 голосов
/ 12 октября 2011

Вы предполагаете, что данные не внесены в базу данных неправильно.

при загрузке файла вы должны сделать что-то вроде этого:

 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).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...