В форуме достаточно часто
поднимается вопрос типа «а
как отобразить картинку,
если она сохранена в БД?». И
ответ всегда звучал примерно
так: «создать файл, который
получает картинку из БД и
пишет ее содержимое клиенту
предварительно установив
правильный ContentType».
Но зачем использовать
дополнительный файл для
получения картинки, если в
ASP.NET есть такое
замечательно средство
обработки запросов, как
HttpHandler? :)
Что же такое HttpHandler
и на что он похож?
Фактически HttpHandler это
тот же ISAPI фильтр,
обрабатывающий http запросы.
Любой запрос, приходящий на
ASP.NET веб приложение, в
итоге будет обработан одним
из HttpHandlerов, и от этого
никуда не деться. Некоторые
HttpHandlerы передают
выполнение запроса другим
классам (например классу
вызываемой страницы), другие
же сами обрабатывают запрос
и возвращают результат
клиенту. Но это в данном
случае не суть важно. Важно
то, что Microsoft
предоставила возможность
разработчикам с легкостью
писать свои HttpHandlerы.
Продолжим рассмотрение
нашей задачи – получения
изображения из базы данных.
Пусть в БД есть таблица
Picture следующей структуры:
CREATE TABLE pictures (
id int IDENTITY(1,1) NOT NULL ,
pic image NOT NULL
)
Мы хотим получать из этой
БД изображение по его
уникальному идентификатору
(значению поля id). При это
мы не хотим создавать
никаких дополнительных
файлов. И, как я уже
упоминал, этого и не
потребуется - все может быть
сделано с помощью
HttpHandler.
Для того, чтобы класс мог
быть зарегистрирован как
HttpHandler, необходимо
всего лишь реализовать в нем
интерфейс
System.Web.IHttpHandler,
имеющий одно get свойство и
один метод. Попробуем
сделать это :)
Начнем с имени класса:
namespace PictureHandler
{ public class PictureHandler : IHttpHandler
{
Затем реализуем свойство
IsReusable, указывающее на
то, может ли наш класс
вызываться без повторной
инициализации
bool IHttpHandler.IsReusable
{
get { return true; }
}
И, наконец, перейдем к
самому интересному –
реализации метода
ProcessRequest, выполняющего
реальную обработку запроса.
Напомню, что мы хотим по
уникальному идентификатору
картинки вернуть саму
картинку:
void IHttpHandler.ProcessRequest(HttpContext context)
{
Получаем ссылки на
объекты Request и Response
запроса.
HttpRequest Request = context.Request;
HttpResponse Response = context.Response;
Получаем значение
уникального идентификатора
картинки
int ID = Int32.Parse(Request.QueryString["ID"]);
Создаем подключение к БД
и получаем картинку по ее
уникальному идентификатору
SqlConnection myConn = new SqlConnection("server=localhost;uid=sa;pwd=;database=pictures");
SqlCommand myCmd = new SqlCommand("select pic from pictures where id = @id", myConn);
myCmd.Parameters.Add("@id", empID);
myConn.Open();
SqlDataReader rdr = myCmd.ExecuteReader();
Я здесь не делал проверки
на существование записи, но
в реальной жизни это конечно
же не помешает :)
rdr.Read();
Устанавливаем правильный
ContentType
Response.ContentType = "image/jpeg";
И пишем содержимое
картинки клиенту.
Response.OutputStream.Write(rdr.GetSqlBinary(0).Value, 0, rdr.GetSqlBinary(0).Length);
Response.End();
rdr.Close();
myConn.Close();
}
}
}
Вот и все – наш
HttpHandler создан. Осталось
подключить его к веб
приложению и он будет готов
к работе.
Для подключения
HttpHandlerов используется
секция <httpHandlers> файла
конфигурации web.config.
Формат строки подключения
HttpHandlerа следующий:
<httpHandlers>
<add verb="(verbs)" path="(путь к файлу)" type="(полное имя класса,имя сборки)" />
</httpHandlers>
Опираясь на это подключим
созданный нами HttpHandler к
веб приложению. Перепишем
скомпилированную сборку в
подкаталог bin веб
приложения и добавим в файл
конфигурации в раздел
<httpHandlers> следующую
строку:
<add verb="*" path="photo.aspx" type="PictureHandler.PictureHandler,PictureHandler" />
Человеческим языком эту
строку можно объяснить так:
при запросе файла photo.aspx
обрабатывать это запрос
HttpHandlerом
PictureHandler.PictureHandler,
находящимся в сборке
PictureHandler. Обратите
внимания – реально файла
photo.aspx в веб приложении
не существует, но если вы
попробуете запросить файл
photo.aspx с правильным
уникальным идентификатором
картинки – вам будет
возвращена эта картинка.
Вот и все. Теперь в любом
месте веб приложения для
вывода картинки с id=10
можно использовать <img
src=”photo.aspx?id=10”>.
PS. Не пытайтесь
используя приведенный выше
пример получить картинки из
таблицы Employees базы
Northwind – все равно ничего
не получится :) В этой
таблице хранятся не
картинки, а OLE объекты. |