Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Технологии программирования / источники / ++часть 2 Совр веб-техн / 21.+ Практ Прим поиск техн в Интерне.rtf
Скачиваний:
195
Добавлен:
10.05.2015
Размер:
13.68 Mб
Скачать

21.6.3. Добавление в поисковое расширение Интернет-магазина визуальных подсказок

Разработаем подсказки в формате XML. При этом хранить большой набор XML файлов не имеет смысла, так как угадать все возможные запросы пользователя не представляется возможным, а для созданных файлов будет сложно поддерживать их актуальность. Также нас не устраивает и создание веб-сервиса, так как при использовании поиска используется HTTP GET.

Для того чтобы реализовать поиск, добавим в корень нашего приложения asp-handler SearchSuggestion.ashx. Соответственно, так как новый класс SearchSuggestion реализует интерфейс IHttpHandler, пользователи и браузер могут обращаться по адресу http://localhost:31770/AWCDShop/SearchSuggestion.ashx для получения результата работу обработчика SearchSuggestion.

Примечание: при работе через IIS может потребоваться изменение файла web.config и ISAPI-фильтров приложения в IIS.

В метод ProcessRequest, который и будет обрабатывать полученный запрос, добавим следующий код:

context.Response.ContentType = "text/plain";

var q = context.Request["query"];

if (q==null) q = "";

DataClassesDataContext dcdc = new DataClassesDataContext

("Data Source=localhost;Initial Catalog=AdventureWorks;Integrated Security=True");

var query = from p in dcdc.Products where p.Name.Contains(q) select p;

query = query.Take(10);

var sb = new StringBuilder();

MemoryStream ms = new MemoryStream();

string str = "";

XmlTextWriter writer = new XmlTextWriter(ms, Encoding.UTF8);

writer.WriteStartDocument();

writer.WriteStartElement("SearchSuggestion");

writer.WriteAttributeString("version","2.0");

writer.WriteAttributeString("xmlns",null, null, "http://opensearch.org/searchsuggest2");

writer.WriteStartElement("Query");

writer.WriteAttributeString("xml", "space",null, "preserve");

writer.WriteValue(q);

writer.WriteEndElement();

writer.WriteStartElement("Section");

foreach (Product p in query)

{

writer.WriteStartElement("Item");

writer.WriteStartElement("Text");

writer.WriteAttributeString("xml", "space", null, "preserve");

writer.WriteValue(p.Name);

writer.WriteEndElement();

writer.WriteStartElement("Url");

writer.WriteAttributeString("xml", "space", null, "preserve");

writer.WriteValue("http://localhost:31770/AWCDShop/products/ProductsSearch.aspx?query="+p.Name);

writer.WriteEndElement();

writer.WriteStartElement("Description");

writer.WriteAttributeString("xml", "space", null, "preserve");

writer.WriteValue((p.ProductModel != null &&

p.ProductModel.ProductModelProductDescriptionCultures.Count > 0)

? p.ProductModel.ProductModelProductDescriptionCultures[0].ProductDescription.

Description

: "");

writer.WriteEndElement();

writer.WriteStartElement("Image");

writer.WriteAttributeString("xml", "space", null, "preserve");

writer.WriteAttributeString("width", "80");

writer.WriteAttributeString("height", "49");

writer.WriteAttributeString("align", "middle");

writer.WriteAttributeString("source",

"http://localhost:31770/AWCDShop/products/images/ProductImages/thumbs/" +

p.ProductProductPhotos[0].ProductPhoto.ThumbnailPhotoFileName);

writer.WriteEndElement();

writer.WriteEndElement();

}

writer.WriteEndElement();

writer.WriteEndElement();

writer.WriteEndDocument();

writer.Flush();

ms.Position = 0;

var sr = new StreamReader(ms);

context.Response.Write(sr.ReadToEnd());

Разберем этот код. Вначале мы определяем Mime-type ответа обработчика как "text/plain". Затем извлекаем переданный через запрос параметр query, и при помощи LINQ выбираем первые 10 продуктов, которые содержат в своем имени переданную строку. Выбирать более 10 не имеет смысла еще и потому, что IE отображает не более 10 подсказок. Далее при помощи класса XMLTextWriter формируем соответствующий XML файл.

Примечание: здесь, как и раньше для картинок и ссылок используются адреса, начинающиеся с http://localhost:31770. В случае использования другого порта для dev-server'а или IIS этот адрес необходимо заменить. В некоторых случаях можно обойтись и использование относительных ссылок, а не абсолютных.

В конце записываем содержимое XML-документа, хранящиеся в потоке ms в Response.

Вот вариант ответа обработчика на запрос "bike":

<?xml version="1.0" encoding="utf-8" ?>

<SearchSuggestion version="2.0" xmlns="http://opensearch.org/searchsuggest2">

<Query xml:space="preserve">bike</Query>

<Section>

<Item>

<Text xml:space="preserve">All-Purpose Bike Stand</Text>

<Url xml:space="preserve">http://localhost:31770/AWCDShop/products/ProductsSearch.aspx?query=All-Purpose Bike Stand</Url>

<Description xml:space="preserve">

Perfect all-purpose bike stand for working on your bike at home. Quick-adjusting clamps and steel construction.

</Description>

<Image xml:space="preserve" width="80" height="49" align="middle"

source="http://localhost:31770/AWCDShop/products/images/ProductImages/thumbs/no_image_available_small.gif" />

</Item>

<Item>

<Text xml:space="preserve">Bike Wash – Dissolver</Text>

<Url xml:space="preserve">

http://localhost:31770/AWCDShop/products/ProductsSearch.aspx?query=Bike Wash – Dissolver

</Url>

<Description xml:space="preserve">

Washes off the toughest road grime; dissolves grease, environmentally safe. 1-liter bottle.

</Description>

<Image xml:space="preserve" width="80" height="49" align="middle"

source="http://localhost:31770/AWCDShop/products/images/ProductImages/thumbs/no_image_available_small.gif" />

</Item>

<Item>

<Text xml:space="preserve">Hitch Rack – 4-Bike</Text>

<Url xml:space="preserve">

http://localhost:31770/AWCDShop/products/ProductsSearch.aspx?query=Hitch Rack – 4-Bike

</Url>

<Description xml:space="preserve">

Carries 4 bikes securely; steel construction, fits 2" receiver hitch.

</Description>

<Image xml:space="preserve" width="80" height="49" align="middle"

source="http://localhost:31770/AWCDShop/products/images/ProductImages/thumbs/no_image_available_small.gif" />

</Item>

<Item>

<Text xml:space="preserve">Mountain Bike Socks, L</Text>

<Url xml:space="preserve">

http://localhost:31770/AWCDShop/products/ProductsSearch.aspx?query=Mountain Bike Socks, L

</Url>

<Description xml:space="preserve">

Combination of natural and synthetic fibers stays dry and provides just the right cushioning.

</Description>

<Image xml:space="preserve" width="80" height="49" align="middle"

source="http://localhost:31770/AWCDShop/products/images/ProductImages/thumbs/no_image_available_small.gif" />

</Item>

<Item>

<Text xml:space="preserve">Mountain Bike Socks, M</Text>

<Url xml:space="preserve">

http://localhost:31770/AWCDShop/products/ProductsSearch.aspx?query=Mountain Bike Socks, M

</Url>

<Description xml:space="preserve">

Combination of natural and synthetic fibers stays dry and provides just the right cushioning.

</Description>

<Image xml:space="preserve" width="80" height="49" align="middle"

source="http://localhost:31770/AWCDShop/products/images/ProductImages/thumbs/no_image_available_small.gif" />

</Item>

</Section>

</SearchSuggestion>

Примечание: стоит обратить внимание, что у большинства сформированных тегов указаны пространства имен. Если их не указать, то подсказки в IE8 отображаться не будут.

Теперь запустим браузер и проверим результат работы рис.21.9.

Рис. 21.9.  Пример работы поискового расширения интернет-магазина Adventure Works