[IE8] 整合 - 建構支援搜尋提供者、加速器、網頁快訊的網站

  • 8206
  • 0
  • IE
  • 2009-04-17

在上一篇文章中,我介紹了網頁快訊與GridView的應用,在這篇文章中,我們將持續加強上次的範例,讓這個書籍搜尋網站支援網頁快訊、加速器及搜尋提供者,
為想要為自己網站加上這些功能的朋友們,提供一個較完整的範例。

 

[IE8] 整合 - 建構支援搜尋提供者、加速器、網頁快訊的網站
 
 
 
/黃忠成
 
 
 
加速器及搜尋提供者,為想要為自己網站加上這些功能的朋友們,提供一個較完整的範例。
 
註:如果你對搜尋提供者及加速器尚未了解,那麼請參考我於MSDN上的文章,連結如下:
下載範例內含(ASPJSP.NETPHP等實作Web Slice、加速器、搜尋提供者原始碼)
或是參考點部落其它網友的相關文章。
 
建立Web Slices
 
 這已經在上一篇文章中實作過了,本文就不再贅述了,唯一不同的是此次我使用了ASP.NET 3.5ListView控件來呈現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/"
                                              xmlns:ie=http://schemas.microsoft.com/Search/2008/>
     <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
 
 
只是預覽視窗真的太小了....這種應用只是酷而已,實用性上有待商確。
 
 
註:本文使用之書籍圖片為該出版社所有,如有不妥之處,請告知,我會儘速移除.
 
 
範例下載