В форуме достаточно часто поднимается вопрос типа <а как отобразить картинку,
если она сохранена в БД?>. И ответ всегда звучал примерно так: <создать
файл, который получает картинку из БД и пишет ее содержимое клиенту
предварительно установив правильный 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;
4 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 объекты.