在上一篇文章中,我介紹了網頁快訊與GridView的應用,在這篇文章中,我們將持續加強上次的範例,讓這個書籍搜尋網站支援網頁快訊、加速器及搜尋提供者,
為想要為自己網站加上這些功能的朋友們,提供一個較完整的範例。
[IE8] 整合 - 建構支援搜尋提供者、加速器、網頁快訊的網站
文/黃忠成
加速器及搜尋提供者,為想要為自己網站加上這些功能的朋友們,提供一個較完整的範例。
註:如果你對搜尋提供者及加速器尚未了解,那麼請參考我於MSDN上的文章,連結如下:
下載範例內含(ASP、JSP、.NET、PHP等實作Web Slice、加速器、搜尋提供者原始碼)
或是參考點部落其它網友的相關文章。
建立Web Slices
這已經在上一篇文章中實作過了,本文就不再贅述了,唯一不同的是此次我使用了ASP.NET 3.5的ListView控件來呈現Web Slices,
如果你是使用ASP.NET 2.0版,那麼請持續使用前篇的範例。
程式1
Books.aspx |
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Books.aspx.vb" Inherits="SearchBooks" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT * FROM [BOOKS]"> </asp:SqlDataSource> <asp:ListView ID="ListView1" runat="server" DataKeyNames="BOOK_ID" DataSourceID="SqlDataSource1"> <ItemTemplate> <div id='<%# Eval("BOOK_ID") + "_SLICE" %>' class="hslice"> <span class="entry-title" style="visibility: hidden"> <%# Eval("Name") %></span> <a href='<%#"BookDetail.aspx?ID="+Eval("BOOK_ID") %>' rel="feedurl" style="visibility: hidden"></a> <div class="entry-content"> <p> <%# Eval("Name") %></p> <asp:Image ID="Image1" runat="server" Height="120" Width="80" ImageUrl='<%# Eval("PIC_URL") %>' /> <br /> BID Price: <asp:Label ID="Label1" runat="server" Text='<%# Eval("BID_PRICE") %>' /> </div> </div> </ItemTemplate> <EmptyDataTemplate> <table id="Table1" runat="server" style=""> <tr> <td> No data was returned. </td> </tr> </table> </EmptyDataTemplate> <LayoutTemplate> <div id="layoutRoot" runat="server"> <div id="itemPlaceholder" runat="server"> </div> </div> </LayoutTemplate> </asp:ListView> <asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" PageSize="5"> <Fields> <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="True" ShowLastPageButton="True" /> </Fields> </asp:DataPager> </div> </form> </body> </html> |
BookDetail.aspx的程式碼則與上篇文章完全相同,就略過不列了,讀者們可自行下載範例或是至前篇文章觀看。
建構搜尋提供者
接下來我們開始實作搜尋提供者,相關的資料已經有很多了,所以我就略過基礎不談,直接深入實作部份。
要實作搜尋提供者有兩個重點,一是提供一個具搜尋功能的網頁,並提供讓使用者安裝搜尋提供者的按紐,
這可以用Books.aspx來修改,如程式2。
程式2
Books.aspx(更一版) |
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Books.aspx.vb" Inherits="SearchBooks" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <input type="button" value="安裝搜尋提供者" onclick= "window.external.AddSearchProvider('http://localhost:20541/DemoSP/SProvider.xml')" /> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT * FROM [BOOKS] WHERE ([NAME] LIKE '%'+@NAME+'%')"> <SelectParameters> <asp:QueryStringParameter DefaultValue="%" Name="NAME" QueryStringField="kw" Type="String" /> </SelectParameters> </asp:SqlDataSource> ......................... |
第二點需要提供一個符合Open Search規格的XML定義檔,如程式3。
程式3
SProvider.xml |
<?xmlversion="1.0"encoding="utf-8" ?> <OpenSearchDescriptionxmlns="http://a9.com/-/spec/opensearch/1.1/" > <ShortName>Books Search</ShortName> <Description>Searching Books</Description> <Tags>Samples</Tags> <Contact>code6421@mail.tw</Contact>> <Urltype="text/html" template="http://localhost:20541/DemoSP/Books.aspx?kw={searchTerms}"/> <LongName>Search Books</LongName> <Developer>code6421</Developer> <Attribution> Copyright 2009, CT Inc., All Rights Reserved </Attribution> <SyndicationRight>open</SyndicationRight> <AdultContent>false</AdultContent> <Language>zh-TW</Language> <OutputEncoding>UTF-8</OutputEncoding> <InputEncoding>UTF-8</InputEncoding> </OpenSearchDescription> |
完成後執行,使用者便可直接於Books.aspx網頁安裝搜尋提供者,也可正常使用。
圖1
圖2
打上一些關鍵字按下Enter鍵後,便導向我們的Books.aspx網頁。
圖3
實作搜尋建議服務
規格中定義了一個名為【搜尋建議】的服務規格,實作此規格的搜尋提供者,IE 8會在使用者鍵入關鍵字時同時Open Search
以下拉視窗顯示由【搜尋建議】服務所回傳的資訊。
除了支援此規格外,IE 8也延伸了此規格,允許我們在每個搜尋建議字中加入圖片,此功能稱為【視覺化搜尋建議】。
網路上關於此的文章也很多了,所以本文也不再贅述了,相對的,在範例裡我特別使用了VB.NET + LINQ To XML,為讀者們展示
VB.NET 2008 + LINQ To XML後,實作輸出XML的網頁有多簡單。
程式4
SearchSuggestion.aspx |
Imports System.Data Imports System.Data.SqlClient Imports System.Xml.Linq Imports <xmlns='http://opensearch.org/searchsuggest2'> Partial Class SearchSuggestion Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not (Request.QueryString("kw") Is Nothing) Then Using conn = New SqlConnection(ConfigurationManager.ConnectionStrings( "NorthwindConnectionString").ConnectionString) conn.Open() Dim cmd = New SqlCommand( "SELECT * FROM BOOKS WHERE NAME LIKE @NAME", conn) cmd.Parameters.AddWithValue("@NAME", "%" & Request.QueryString("kw") & "%") Dim xml = _ <?xml version="1.0"?> <SearchSuggestion version="2.0"> <Query><%= Request.QueryString("kw") %></Query> <Section></Section> </SearchSuggestion> Dim sChilds = xml...<Section>(0) Using reader = cmd.ExecuteReader(CommandBehavior.CloseConnection) While reader.Read() Dim childElem = _ <Item> <Text><%= reader.GetString(reader.GetOrdinal("NAME")) %></Text> <Description> <%= reader.GetDouble(reader.GetOrdinal("BID_PRICE")).ToString() %> </Description> <Url> http://localhost:20541/DemoSP/BookDetail.aspx?ID=<%= HttpUtility.UrlEncode(reader.GetString(reader.GetOrdinal("BOOK_ID"))) %> </Url> <Image source=<%= "http://localhost:20541/DemoSP/" + _ reader.GetString(reader.GetOrdinal("PIC_URL")) %> alt="Image" height="50" width="40" align="middle"> </Image> </Item> ' remove the default namespace from item element,because IE 8 can't recognize it..... childElem.RemoveAttributes() sChilds.Add(childElem) End While End Using Response.Clear() Response.ContentType = "text/xml" Response.Write(xml) Response.Flush() Response.End() End Using End If End Sub End Class |
有一點需特別說明,在Open Search規格中,並未明確指定子Element的Namespace規格,所以IE 8不允許在Item項目使用Namespace,
但LINQ To XML會自動將父Element的Namespace帶入子Element,所以最終輸出的XML中,Item這個Element將會套用SearchSuggestion的Namespace,
導致IE8不認得回傳的資訊。
為了解決此問題,於最後我們使用RemoveAttributes函式來移除這個自動繼承下來的Namespace。
此網頁輸出的XML如下圖。
圖4
記得還要修改SProvider.XML,加上搜尋建議的網頁資訊。
程式5
SProvider.xml |
<?xmlversion="1.0"encoding="utf-8" ?> <OpenSearchDescriptionxmlns="http://a9.com/-/spec/opensearch/1.1/" > <ShortName>Books Search</ShortName> <Description>Searching Books</Description> <Tags>Samples</Tags> <Contact>code6421@mail.tw</Contact>> <Urltype="text/html" template="http://localhost:20541/DemoSP/Books.aspx?kw={searchTerms}"/> <Urltype="application/x-suggestions+xml" <LongName>Search Books</LongName> <Developer>code6421</Developer> <Attribution> Copyright 2009, CT Inc., All Rights Reserved </Attribution> <SyndicationRight>open</SyndicationRight> <AdultContent>false</AdultContent> <Language>zh-TW</Language> <OutputEncoding>UTF-8</OutputEncoding> <InputEncoding>UTF-8</InputEncoding> </OpenSearchDescription> |
整個完成後的執行結果如下圖。
圖5
加上建議使用搜尋提供者的Tag
IE 8允許網頁設計者在網頁上加上一個LINK TAG,告知使用者本網站有建議使用的搜尋提供者,當使用者開啟此網站時,若尚未安裝此建議搜尋提供者時,
右上角選取搜尋提供者的下拉盒會呈橘色,如下所示。
圖6
拉開下拉盒時,即可在未安裝該搜尋提供者的情況下,直接使用其功能。
圖7
圖8
不過由於此搜尋提供者仍處於未安裝狀態,所以搜尋建議字的功能會被關閉,而且在使用者離開此網頁後,此搜尋提供者也會自動被移除。
要使用完整功能,使用者可以透過網頁上的按紐來安裝,或是直接點選新增搜尋提供者來安裝。
圖9
讓成為加速器的搜尋提供者更完整
預設情況下,當使用者安裝搜尋提供者時,IE 8會預設將其安裝為搜尋提供者及加速器,是的!搜尋提供者也可以是一個加速器,不過這有一個問題,
那就是這個加速器沒有預覽畫面。
圖10
會出現此情況的原因是因為我們並未在搜尋提供者的XML定義檔(SProvider.xml)中加上預覽網頁的資訊,修改一下即可。
程式6
SProvider.xml |
<?xmlversion="1.0"encoding="utf-8" ?> <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" <ShortName>Books Search</ShortName> <Description>Searching Books</Description> <Tags>Samples</Tags> <Contact>code6421@mail.tw</Contact>> <Urltype="text/html" template="http://localhost:20541/DemoSP/Books.aspx?kw={searchTerms}"/> <Urltype="application/x-suggestions+xml" <ie:PreviewUrltype="text/html" <LongName>Search Books</LongName> <Developer>code6421</Developer> <Attribution> Copyright 2009, CT Inc., All Rights Reserved </Attribution> <SyndicationRight>open</SyndicationRight> <AdultContent>false</AdultContent> <Language>zh-TW</Language> <OutputEncoding>UTF-8</OutputEncoding> <InputEncoding>UTF-8</InputEncoding> </OpenSearchDescription> |
由於預覽畫面是較小(320x240)的,所以我們另外提供一個AccPreview.aspx來顯示。
程式7
AccPreview.xml |
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="AccPreview.aspx.vb" Inherits="AccPreview" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT TOP 6 * FROM [BOOKS] WHERE ([NAME] LIKE '%'+@NAME+'%')"> <SelectParameters> <asp:QueryStringParameter DefaultValue="%" Name="NAME" QueryStringField="kw" Type="String" /> </SelectParameters> </asp:SqlDataSource> <asp:ListView ID="ListView1" runat="server" DataKeyNames="BOOK_ID" DataSourceID="SqlDataSource1" GroupItemCount="3"> <ItemTemplate> <td align="center"> <a href='BookDetail.aspx?ID=<%# Eval("BOOK_ID") %>' title='<%# Eval("NAME") %>' target="_blank"> <img src='<%# Eval("PIC_URL") %>' height="120px" width="80px" alt='<%# Eval("NAME") %>' /> </a> </td> </ItemTemplate> <GroupTemplate> <tr runat="server" id="BookRow"> <td runat="server" id="itemPlaceholder" /> </tr> </GroupTemplate> <EmptyDataTemplate> <table id="Table1" runat="server" style=""> <tr> <td> No data was returned. </td> </tr> </table> </EmptyDataTemplate> <LayoutTemplate> <table cellspacing="9"> <tr id="groupPlaceholder" runat="server"> </tr> </table> </LayoutTemplate> </asp:ListView> </div> </form> </body> </html> |
執行結果如下圖。
圖11
另一點較有趣的是,預覽視窗其實一個小型的瀏覽器,所以你可以在預覽網頁中撰寫JavaScript並執行,或是使用ListView+DataPager進行分頁瀏覽,如下圖。
圖12
只是預覽視窗真的太小了....這種應用只是酷而已,實用性上有待商確。
註:本文使用之書籍圖片為該出版社所有,如有不妥之處,請告知,我會儘速移除.
範例下載