Рендеринг изображения в asp.net MVC - PullRequest
1 голос
/ 08 июля 2011

Мой сценарий таков:

Я создаю пользовательский отчет на основе хранимой процедуры, которая возвращает три столбца (person_id [long], name [varchar (100)], age [int], photo [image]). Это столбцы и типы в моей таблице базы данных.

Сейчас я использую что-то подобное для каждого изображения отчета.

<img src="<%= Url.Action("ShowImage", "Reports", new {personId = result["PERSON_ID"]}) %>" />

с ShowImage, равным

 public virtual ActionResult ShowImage(long? personId)
    {
            try
            {
                if (personId.HasValue)
                {
                    byte[] imageArray = StudentClient.GetPersonPhotoById(personId.Value);
                    if (imageArray == null)
                        return File(noPhotoArray, "image/jpg");

                    #region Validate that the uploaded picture is an image - temporary code

                    // Get Mime Type
                    byte[] buffer = new byte[256];
                    buffer = imageArray.Take(imageArray.Length >= 256 ? 256 : imageArray.Length).ToArray();
                    var mimeType = UrlmonMimeType.GetMimeType(buffer);

                    if (String.IsNullOrEmpty(mimeType) || mimeType.IndexOf("image") == -1)
                        return File(noPhotoArray, "image/jpg");

                    #endregion

                    return File(imageArray, "image/jpg");
                }
            }
            catch
            {
                return File(noPhotoArray, "image/jpg");
            }
    }

Я хотел бы использовать какую-то альтернативу, потому что это очень напряженно из-за того, что ShowImage () вызывает метод службы StudentClient.GetPersonPhotoById (personId.Value); за каждую отдельную картинку, что означает множество вызовов для службы и БД.

Я бы хотел использовать этот столбец фотографий, который возвращает массив байтов, вместо использования столбца Person_id с помощью метода контроллера ShowImage.

Это практически уменьшит количество обращений к службе до 0 и будет использовать фактические данные из столбца изображения. Это кажется довольно простым, но я изо всех сил пытаюсь найти решение.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 08 июля 2011

Самое простое решение - использовать OutputCache . Кроме того, вы можете установить расположение кэша для клиента, и браузер будет кэшировать изображения после их загрузки. VaryByParam даст вам возможность кэшировать изображения в зависимости от personId.

0 голосов
/ 11 июля 2011

Вы можете использовать это как источник изображения.

src="data:image/jpg;base64,<%= System.Convert.ToBase64String(result["PHOTO"] as byte[]) %>"
0 голосов
/ 08 июля 2011

Существует довольно изящный метод, при котором вы можете передавать двоичные данные напрямую с SQL Server на клиент через веб-сервер.

Это мой код для этого:

    public void StreamFile(Stream stream)
    {
        DbDataReader dr = LoadDbStream();
        if (!dr.Read())
            return;

        const int BUFFERSIZE = 512;
        byte[] Buffer = new byte[BUFFERSIZE];
        long StartIndex = 0;
        long Read = dr.GetBytes(0, StartIndex, Buffer, 0, BUFFERSIZE);

        while (Read == BUFFERSIZE)
        {
            stream.Write(Buffer, 0, BUFFERSIZE);

            StartIndex += BUFFERSIZE;
            Read = dr.GetBytes(0, StartIndex, Buffer, 0, BUFFERSIZE);
        }
        stream.Write(Buffer, 0, (int)Read);
    }

    private DbDataReader LoadDbStream()
    {
        DbCommand cmd = Cms.Data.GetCommand("SELECT Data FROM CMS_Files WHERE FileId = @FileId", "@FileId", Id.ToString());
        cmd.CommandType = System.Data.CommandType.Text;

        cmd.Connection.Open();
        return cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection);
    }

Объект команды является обычным объектом команды. Ключевой частью является флаг CommandBehavior.SequentialAccess, поскольку он заставляет сервер sql отправлять данные только по запросу. Поэтому вы можете читать столбцы только в том порядке, в котором они указаны в запросе. другая точка, которую нужно сделать, - поток должен быть выходным потоком из буфера вывода запроса и выключения.

Соедините это с выходным кэшированием, и вы уменьшите нагрузку на сервер.

Simon

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