none
Файл становиться не рабочим после загрузки в БД и последующей выгрузке. RRS feed

  • Вопрос

  • Коллеги, привет!

    ASP MVC, C#, MS SQL 2012. Приложение загружает работающий файл в БД, далее при получении файла из БД возвращается файл который уже не возможно открыть или если это офисный файл, содержатся непонятный символы. Такое впечатление что меняется кодировка файла. 

    Код, который возвращает файл клиенту.

    FileContentResult newFile = new FileContentResult(fileContent, "application/octet-stream");          

    newFile.FileDownloadName = fileName;               

    return newFile;

    Может кто сталкивался, подскажите пожалуйста:)

    24 июня 2014 г. 10:38

Ответы

  • Так вы же создаёте пустой массив байтов, отсюда и все беды.

     byte[] bytes = new byte[file.ContentLength];
    //...
    //А тут неизвестно что передаёте.
    cmd.Parameters.Add("@file_stream", SqlDbType.VarBinary).Value = file;

    А на сервер пытаетесь отправить не байты, а строку объекта файла, которая содержит нули. Вот внимательно изучите этот пример, там детально всё описано.


    Сделаем содержимое сообщества лучше, вместе!

    • Помечено в качестве ответа ilyushin 25 июня 2014 г. 6:17
    25 июня 2014 г. 6:02
    Модератор

Все ответы

  • Код записи и чтения в студию пожалуйста. И ещё какой тип для хранения используется.

    Сделаем содержимое сообщества лучше, вместе!

    24 июня 2014 г. 11:53
    Модератор
  • Код записи и чтения ниже. Файлы храняться в FileTable.

    public string CreateFile(HttpPostedFileBase file)
            {
                string stream_id = String.Empty;

                try
                {
                    //считаем загруженный файл в массив
                    byte[] bytes = new byte[file.ContentLength];

                    string constr = ConfigurationManager.ConnectionStrings["PokrovConnectionString"].ConnectionString;

                    using (TransactionScope ts = new TransactionScope())
                    {
                        using (SqlConnection con = new SqlConnection(constr))
                        {
                            string query = "DECLARE @MyTableVar TABLE (stream_id uniqueidentifier);"
                                + "INSERT INTO Files(name, file_stream) OUTPUT INSERTED.stream_id INTO @MyTableVar";                                 + "VALUES(@name, @file_stream);"
                                + "SELECT TOP (1) @Identity = stream_id FROM @MyTableVar;";
                            using (SqlCommand cmd = new SqlCommand(query))
                            {
                                cmd.Connection = con;
                                cmd.Parameters.Add("@name", SqlDbType.VarChar).Value = Path.GetFileName(file.FileName);
                                cmd.Parameters.Add("@file_stream", SqlDbType.VarBinary).Value = bytes;
                                SqlParameter idParam = cmd.Parameters.Add("@Identity", SqlDbType.NVarChar, 1000);
                                idParam.Direction = ParameterDirection.Output;
                                con.Open();
                                cmd.ExecuteNonQuery();
                                con.Close();
                                stream_id = (string)idParam.Value;
                            }
                        }
                        ts.Complete();
                    }
                }
                catch { }

                return stream_id;

            }

            public FileContentResult GetFile(Guid stream_id,  string contentType = "application/octet-stream")
            {
                SqlDataReader rdr;
                byte[] fileContent = null;
                string mimeType = "";
                string fileName = "";
                string connect = ConfigurationManager.ConnectionStrings["PokrovConnectionString"].ConnectionString;
                bool success = false;

                using (var conn = new SqlConnection(connect))
                {
                    var qry = "SELECT file_stream, name, file_type FROM Files WHERE stream_id = @stream_id";
                    var cmd = new SqlCommand(qry, conn);
                    cmd.Parameters.AddWithValue("@stream_id", stream_id);
                    conn.Open();

                    try
                    {
                        rdr = cmd.ExecuteReader();
                        if (rdr.HasRows)
                        {
                            rdr.Read();
                            fileContent = (byte[])rdr["file_stream"];
                            mimeType = rdr["file_type"].ToString();
                            fileName = rdr["name"].ToString();
                        }
                        success = true;
                    }
                    catch
                    {
                        return null;
                    }
                }

                if (success == true)
                {
                    FileContentResult newFile = new FileContentResult(fileContent, contentType);
                    newFile.FileDownloadName = fileName;
                    return newFile;
                }
                return null;
            }

           

    24 июня 2014 г. 12:18
  • Файл отправляется с клиента?

    Нет кода который читает файл в byte[]

    Скорее всего проблема в кодировке при чтении файла из потока (при загрузке на сервер). 


    • Изменено Bazzzy 24 июня 2014 г. 15:13
    24 июня 2014 г. 15:12
  • Как нет, есть в самом начале первой процедуры

                    //считаем загруженный файл в массив
                    byte[] bytes = new byte[file.ContentLength];

    Насчет кодировки я тоже думал, но в какой момент она меняется, и почему?

    24 июня 2014 г. 18:12
  • Так вы же создаёте пустой массив байтов, отсюда и все беды.

     byte[] bytes = new byte[file.ContentLength];
    //...
    //А тут неизвестно что передаёте.
    cmd.Parameters.Add("@file_stream", SqlDbType.VarBinary).Value = file;

    А на сервер пытаетесь отправить не байты, а строку объекта файла, которая содержит нули. Вот внимательно изучите этот пример, там детально всё описано.


    Сделаем содержимое сообщества лучше, вместе!

    • Помечено в качестве ответа ilyushin 25 июня 2014 г. 6:17
    25 июня 2014 г. 6:02
    Модератор
  • Yatajga спасибо огромное, поправил в процедуре сохранения файла в базу этот кусок кода и все заработало :)

                    int size = file.ContentLength;
                    string name = file.FileName;               
                    string contentType = file.ContentType;
                    byte[] bytes = new byte[size];
                    file.InputStream.Read(bytes, 0, size);

    25 июня 2014 г. 6:22
  • Рад был помочь.

    Сделаем содержимое сообщества лучше, вместе!

    25 июня 2014 г. 6:23
    Модератор