Vytvoření vlastního databázově řízeného zprostředkovatele mapy webu (VB)
Scott Mitchell
Výchozí zprostředkovatel mapy webu v ASP.NET 2.0 načte data ze statického souboru XML. I když je zprostředkovatel založený na jazyce XML vhodný pro mnoho malých a středně velkých webů, větší webové aplikace vyžadují dynamičtější mapu webu. V tomto kurzu vytvoříme vlastního zprostředkovatele mapy webu, který načte data z vrstvy obchodní logiky, která zase načte data z databáze.
Úvod
ASP.NET 2.0 funkce mapy webu umožňuje vývojáři stránky definovat mapu webu webové aplikace v určitém trvalém médiu, například v souboru XML. Po definování mohou být data mapy webu přístupná prostřednictvím kódu programu prostřednictvím SiteMap
třídy v System.Web
oboru názvů nebo prostřednictvím různých navigačních webových ovládacích prvků, jako jsou Ovládací prvky SiteMapPath, Menu a TreeView. Systém mapy webu používá model zprostředkovatele, aby bylo možné vytvořit a připojit k webové aplikaci různé implementace serializace mapy webu. Výchozí zprostředkovatel mapy webu, který se dodává s ASP.NET 2.0, zachovává strukturu mapy webu v souboru XML. Zpátky v kurzu Stránky předlohy a navigace na webu jsme vytvořili soubor s názvem Web.sitemap
, který obsahoval tuto strukturu, a aktualizovali jsme jeho XML o každou novou část kurzu.
Výchozí zprostředkovatel mapování webů založený na JAZYCE XML funguje dobře, pokud je struktura mapy webu poměrně statická, například pro tyto kurzy. V mnoha scénářích je však potřeba dynamičtější mapa webu. Představte si mapu webu zobrazenou na obrázku 1, kde se jednotlivé kategorie a produkty zobrazují jako oddíly ve struktuře webu. Při této mapě webu může návštěva webové stránky odpovídající kořenovému uzlu zobrazit seznam všech kategorií, zatímco při návštěvě konkrétní webové stránky kategorií by se zobrazily produkty dané kategorie a zobrazení konkrétní webové stránky produktu by zobrazily podrobnosti o produktu.
Obrázek 1: Kategorie a produkty – make-up struktury mapy webu (kliknutím zobrazíte obrázek s plnou velikostí)
I když by tato struktura založená na kategoriích a produktech mohla být pevně zakódovaná do Web.sitemap
souboru, soubor by se měl aktualizovat při každém přidání kategorie nebo produktu, odebrání nebo přejmenování. V důsledku toho by byla údržba mapy webu značně zjednodušená, pokud by byla její struktura načtena z databáze nebo ideálně z vrstvy obchodní logiky architektury aplikace. Díky tomu se při přidání, přejmenování nebo odstranění produktů a kategorií mapa webu automaticky aktualizuje tak, aby odrážela tyto změny.
Vzhledem k tomu, ASP.NET 2.0 s serializace mapy webu je postavena na základě modelu poskytovatele, můžeme vytvořit vlastního zprostředkovatele mapy webu, který vezme svá data z alternativního úložiště dat, jako je databáze nebo architektura. V tomto kurzu vytvoříme vlastního zprostředkovatele, který načte data z BLL. Pojďme začít!
Poznámka:
Vlastní zprostředkovatel mapy webu vytvořený v tomto kurzu je úzce propojený s architekturou a datovým modelem aplikace. Jeff Prosise s Storing Site Maps in SQL Server and The SQL Site Map Provider You ve Been Waiting For articles examine a generalized approach to storing site map data in SQL Server.
Krok 1: Vytvoření vlastních webových stránek zprostředkovatele mapy webu
Než začneme vytvářet vlastního zprostředkovatele mapy webu, nejdřív přidáme ASP.NET stránky, které budeme pro účely tohoto kurzu potřebovat. Začněte přidáním nové složky s názvem SiteMapProvider
. Dále do této složky přidejte následující ASP.NET stránky a nezapomeňte přidružit každou stránku ke stránce předlohy Site.master
:
Default.aspx
ProductsByCategory.aspx
ProductDetails.aspx
Do složky přidejte CustomProviders
také podsložku App_Code
.
Obrázek 2: Přidání ASP.NET stránek pro kurzy související s poskytovatelem mapy webu
Vzhledem k tomu, že pro tuto část existuje jenom jeden kurz, nemusíme Default.aspx
vypisovat kurzy oddílů. Default.aspx
Místo toho zobrazí kategorie v ovládacím prvku GridView. Budeme se s tím zabývat v kroku 2.
V dalším kroku aktualizujte Web.sitemap
odkaz na Default.aspx
stránku. Konkrétně přidejte následující kód za ukládání do mezipaměti <siteMapNode>
:
<siteMapNode
title="Customizing the Site Map" url="~/SiteMapProvider/Default.aspx"
description="Learn how to create a custom provider that retrieves the site map
from the Northwind database." />
Po aktualizaci Web.sitemap
si chvíli prohlédněte web kurzů prostřednictvím prohlížeče. Nabídka vlevo teď obsahuje položku pro jediný kurz poskytovatele mapy webu.
Obrázek 3: Mapa webu teď obsahuje položku pro kurz zprostředkovatele mapy webu
Hlavním cílem tohoto kurzu je ilustrovat vytvoření vlastního zprostředkovatele mapy webu a konfiguraci webové aplikace pro použití tohoto zprostředkovatele. Konkrétně vytvoříme zprostředkovatele, který vrátí mapu webu, která obsahuje kořenový uzel spolu s uzlem pro každou kategorii a produkt, jak je znázorněno na obrázku 1. Obecně platí, že každý uzel na mapě webu může zadat adresu URL. Pro naši mapu webu bude ~/SiteMapProvider/Default.aspx
adresa URL kořenového uzlu , která zobrazí seznam všech kategorií v databázi. Každý uzel kategorie v mapě webu bude mít adresu URL odkazující na ~/SiteMapProvider/ProductsByCategory.aspx?CategoryID=categoryID
, která zobrazí seznam všech produktů v zadaném ID kategorie. Nakonec každý uzel mapy webu produktu bude odkazovat na ~/SiteMapProvider/ProductDetails.aspx?ProductID=productID
, který zobrazí podrobnosti o konkrétním produktu.
Abychom mohli začít, musíme vytvořit Default.aspx
, ProductsByCategory.aspx
a ProductDetails.aspx
stránky. Tyto stránky jsou dokončeny v krocích 2, 3 a 4. Vzhledem k tomu, že tah tohoto kurzu je na poskytovatelích map webu a od předchozích kurzů jsme se zabývali vytvářením těchto typů sestav předlohy a podrobností s více stránkami, pospěšíme si kroky 2 až 4. Pokud potřebujete aktualizovatel při vytváření sestav předlohy a podrobností, které pokrývají více stránek, vraťte se k kurzu Filtrování předlohy a podrobností napříč dvěma stránkami .
Krok 2: Zobrazení seznamu kategorií
Default.aspx
Otevřete stránku ve SiteMapProvider
složce a přetáhněte Objekt GridView z panelu nástrojů do Návrháře a nastavte ho ID
na Categories
. Z inteligentní značky GridView vytvořte vazbu na nový ObjectDataSource pojmenovaný CategoriesDataSource
a nakonfigurujte ho tak, aby načetl svá data pomocí CategoriesBLL
metody třídy s GetCategories
. Vzhledem k tomu, že tento Objekt GridView pouze zobrazuje kategorie a neposkytuje možnosti úprav dat, nastavte rozevírací seznamy na kartách UPDATE, INSERT a DELETE na (Žádné).
Obrázek 4: Konfigurace ObjectDataSource pro vrácení kategorií pomocí GetCategories
metody (kliknutím zobrazíte obrázek s plnou velikostí)
Obrázek 5: Nastavení rozevíracích seznamů na kartách UPDATE, INSERT a DELETE na (Žádné) (Kliknutím zobrazíte obrázek v plné velikosti)
Po dokončení průvodce konfigurací zdroje dat sada Visual Studio přidá BoundField pro CategoryID
, CategoryName
, Description
, NumberOfProducts
a BrochurePath
. Upravte GridView tak, aby obsahoval CategoryName
pouze a Description
BoundFields a aktualizovat CategoryName
BoundField s HeaderText
vlastnost Category .
Dále přidejte HyperLinkField a umístěte ho tak, aby bylo pole nejvíce vlevo. DataNavigateUrlFields
Nastavte vlastnost CategoryID
na hodnotu a DataNavigateUrlFormatString
vlastnost na ~/SiteMapProvider/ProductsByCategory.aspx?CategoryID={0}
hodnotu . Text
Nastavte vlastnost zobrazit produkty .
Obrázek 6: Přidání HyperLinkFieldu do gridview Categories
Po vytvoření ObjectDataSource a přizpůsobení polí GridView s budou dva ovládací prvky deklarativní revize vypadat takto:
<asp:GridView ID="Categories" runat="server" AutoGenerateColumns="False"
DataKeyNames="CategoryID" DataSourceID="CategoriesDataSource"
EnableViewState="False">
<Columns>
<asp:HyperLinkField DataNavigateUrlFields="CategoryID"
DataNavigateUrlFormatString=
"~/SiteMapProvider/ProductsByCategory.aspx?CategoryID={0}"
Text="View Products" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
SortExpression="CategoryName" />
<asp:BoundField DataField="Description" HeaderText="Description"
SortExpression="Description" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetCategories"
TypeName="CategoriesBLL"></asp:ObjectDataSource>
Obrázek 7 znázorňuje Default.aspx
zobrazení v prohlížeči. Kliknutím na odkaz Zobrazit produkty kategorie přejdete na odkaz , který ProductsByCategory.aspx?CategoryID=categoryID
vytvoříme v kroku 3.
Obrázek 7: Každá kategorie je uvedena společně s odkazem Na produkty zobrazení (kliknutím zobrazíte obrázek v plné velikosti).
Krok 3: Výpis produktů vybrané kategorie
ProductsByCategory.aspx
Otevřete stránku a přidejte GridView a pojmete ji ProductsByCategory
. Z inteligentní značky vytvořte vazbu GridView na nový ObjectDataSource s názvem ProductsByCategoryDataSource
. Nakonfigurujte ObjectDataSource tak, aby používal metodu ProductsBLL
třídy s GetProductsByCategoryID(categoryID)
a nastavte rozevírací seznamy na (None) na kartách UPDATE, INSERT a DELETE.
Obrázek 8: Použití ProductsBLL
metody třídy GetProductsByCategoryID(categoryID)
(kliknutím zobrazíte obrázek s plnou velikostí)
Poslední krok v průvodci konfigurací zdroje dat zobrazí výzvu ke zdroji parametrů pro ID kategorie. Vzhledem k tomu, že se tyto informace předávají prostřednictvím pole CategoryID
řetězce dotazu , vyberte z rozevíracího seznamu řetězec dotazu a zadejte CategoryID do textového pole QueryStringField, jak je znázorněno na obrázku 9. Dokončete průvodce kliknutím na Dokončit.
Obrázek 9: Použití CategoryID
pole řetězce dotazu pro parametr categoryID (Kliknutím zobrazíte obrázek s plnou velikostí)
Po dokončení průvodce visual Studio přidá odpovídající BoundFields a CheckBoxField do GridView pro pole s daty produktu. Odeberte všechny kromě ProductName
UnitPrice
, a SupplierName
BoundFields. Přizpůsobte si tyto tři vlastnosti BoundFields HeaderText
tak, aby si přečetly produkt, cenu a dodavatele. Naformátujte UnitPrice
BoundField jako měnu.
Dále přidejte HyperLinkField a přesuňte ho na pozici úplně vlevo. Nastavte jeho Text
vlastnost zobrazit podrobnosti, jeho DataNavigateUrlFields
vlastnost na ProductID
a jeho DataNavigateUrlFormatString
vlastnost na ~/SiteMapProvider/ProductDetails.aspx?ProductID={0}
.
Obrázek 10: Přidání hyperlinkfieldu podrobností zobrazení, které odkazuje na ProductDetails.aspx
Po provedení těchto přizpůsobení by deklarativní kód GridView a ObjectDataSource měly vypadat přibližně takto:
<asp:GridView ID="ProductsByCategory" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsByCategoryDataSource"
EnableViewState="False">
<Columns>
<asp:HyperLinkField DataNavigateUrlFields="ProductID"
DataNavigateUrlFormatString=
"~/SiteMapProvider/ProductDetails.aspx?ProductID={0}"
Text="View Details" />
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
HeaderText="Price" HtmlEncode="False"
SortExpression="UnitPrice" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ProductsByCategoryDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProductsByCategoryID" TypeName="ProductsBLL">
<SelectParameters>
<asp:QueryStringParameter Name="categoryID"
QueryStringField="CategoryID" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
Vraťte se k prohlížení Default.aspx
v prohlížeči a klikněte na odkaz Zobrazit produkty pro nápoje. Tím přejdete na ProductsByCategory.aspx?CategoryID=1
zobrazení názvů, cen a dodavatelů produktů v databázi Northwind, která patří do kategorie Nápoje (viz obrázek 11). Tuto stránku můžete dále vylepšit tak, aby obsahovala odkaz pro vrácení uživatelů na stránku výpisu kategorií (Default.aspx
) a ovládací prvek DetailsView nebo FormView, který zobrazuje název a popis vybrané kategorie.
Obrázek 11: Zobrazí se názvy nápojů, ceny a dodavatelé (kliknutím zobrazíte obrázek v plné velikosti).
Krok 4: Zobrazení podrobností o produktu
Na poslední stránce ProductDetails.aspx
se zobrazí podrobnosti o vybraných produktech. Otevřete ProductDetails.aspx
a přetáhněte DetailsView z panelu nástrojů do Návrháře. Nastavte DetailsView s ID
vlastnost ProductInfo
a vymazat jeho Height
a Width
vlastnosti hodnoty. Z inteligentní značky vytvořte vazbu DetailsView na nový ObjectDataSource pojmenovaný ProductDataSource
, konfigurace ObjectDataSource pro načtení dat z ProductsBLL
metody třídy s GetProductByProductID(productID)
. Stejně jako u předchozích webových stránek vytvořených v krocích 2 a 3 nastavte rozevírací seznamy na kartách UPDATE, INSERT a DELETE na (Žádné).
Obrázek 12: Konfigurace ObjectDataSource pro použití GetProductByProductID(productID)
metody (kliknutím zobrazíte obrázek s plnou velikostí)
Poslední krok průvodce konfigurací zdroje dat zobrazí výzvu ke zdroji parametru ProductID . Vzhledem k tomu, že tato data procházejí polem ProductID
řetězce dotazu , nastavte rozevírací seznam na QueryString a QueryStringField textové pole ProductID. Nakonec dokončete průvodce kliknutím na tlačítko Dokončit.
Obrázek 13: Konfigurace parametru PRODUCTID pro načtení jeho hodnoty z ProductID
pole řetězce dotazu (kliknutím zobrazíte obrázek s plnou velikostí)
Po dokončení průvodce konfigurací zdroje dat vytvoří Visual Studio odpovídající BoundFields a CheckBoxField v DetailsView pro pole s daty produktu. Odeberte pole ProductID
, SupplierID
a CategoryID
BoundFields a nakonfigurujte zbývající pole podle potřeby. Po několika estetických konfiguracích vypadaly deklarativní značky DetailsView a ObjectDataSource takto:
<asp:DetailsView ID="ProductInfo" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ProductDataSource"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit" HeaderText="Qty/Unit"
SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
HeaderText="Price" HtmlEncode="False"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock" HeaderText="Units In Stock"
SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder" HeaderText="Units On Order"
SortExpression="UnitsOnOrder" />
<asp:BoundField DataField="ReorderLevel" HeaderText="Reorder Level"
SortExpression="ReorderLevel" />
<asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
<asp:ObjectDataSource ID="ProductDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetProductByProductID" TypeName="ProductsBLL">
<SelectParameters>
<asp:QueryStringParameter Name="productID"
QueryStringField="ProductID" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
Chcete-li otestovat tuto stránku, vraťte se a Default.aspx
klikněte na Zobrazit produkty pro kategorii Nápoje. V seznamu nápojů klikněte na odkaz Zobrazit podrobnosti pro Chai Čaj. Tím přejdete na ProductDetails.aspx?ProductID=1
, který zobrazuje podrobnosti Chai Tea s (viz obrázek 14).
Obrázek 14: Chai Tea s Dodavatel, Kategorie, Cena a Další informace jsou zobrazeny (Kliknutím zobrazíte obrázek v plné velikosti)
Krok 5: Principy vnitřních fungování zprostředkovatele mapy webu
Mapa webu je reprezentována v paměti webového SiteMapNode
serveru jako kolekce instancí, které tvoří hierarchii. Musí existovat přesně jeden kořenový uzel, všechny jiné než kořenové uzly musí mít přesně jeden nadřazený uzel a všechny uzly můžou mít libovolný počet podřízených uzlů. Každý SiteMapNode
objekt představuje oddíl ve struktuře webu; tyto oddíly obvykle mají odpovídající webovou stránku. V důsledku toho třída má vlastnosti, SiteMapNode
jako Title
je , Url
a Description
, které poskytují informace pro oddíl představujeSiteMapNode
. Existuje také Key
vlastnost, která jednoznačně identifikuje každý SiteMapNode
v hierarchii, stejně jako vlastnosti použité k vytvoření této hierarchie ChildNodes
, , ParentNode
, NextSibling
PreviousSibling
a tak dále.
Obrázek 15 znázorňuje obecnou strukturu mapy webu z obrázku 1, ale s podrobnostmi implementace, které jsou načrtnuté podrobněji.
Obrázek 15: Každá SiteMapNode
má vlastnosti like Title
, Url
, Key
a tak dále (kliknutím zobrazíte obrázek s plnou velikostí)
Mapa webu je přístupná prostřednictvím SiteMap
třídy v System.Web
oboru názvů. Tato vlastnost třídy RootNode
vrátí kořenovou SiteMapNode
instanci mapy webu; CurrentNode
vrátí SiteMapNode
vlastnost, jejíž Url
vlastnost odpovídá adrese URL aktuálně požadované stránky. Tato třída se interně používá ASP.NET 2.0 navigační webové ovládací prvky.
Při přístupu k vlastnostem SiteMap
třídy musí serializovat strukturu mapy webu z nějakého trvalého média do paměti. Logika serializace mapy webu však není pevně zakódována do SiteMap
třídy. Místo toho třída určuje, SiteMap
který zprostředkovatel mapy webu se má použít pro serializaci. Ve výchozím nastavení se XmlSiteMapProvider
používá třída , která čte strukturu mapy webu z správně formátovaného souboru XML. S trochou práce ale můžeme vytvořit vlastního poskytovatele mapy webu.
Všichni zprostředkovatelé map webů musí být odvozeni od SiteMapProvider
třídy, která zahrnuje základní metody a vlastnosti potřebné pro zprostředkovatele mapy webu, ale vynechá mnoho podrobností implementace. Druhá třída, StaticSiteMapProvider
rozšiřuje SiteMapProvider
třídu a obsahuje robustnější implementaci potřebných funkcí. Interně ukládá SiteMapNode
instance mapy webu do Hashtable
a poskytuje metody, StaticSiteMapProvider
jako AddNode(child, parent)
je , RemoveNode(siteMapNode),
a Clear()
které přidávají a odebírat SiteMapNode
do interní Hashtable
. XmlSiteMapProvider
je odvozen z StaticSiteMapProvider
.
Při vytváření vlastního zprostředkovatele mapy webu, který rozšiřuje , existují dvě abstraktní metody, které musí být přepsány StaticSiteMapProvider
: BuildSiteMap
a GetRootNodeCore
. BuildSiteMap
, jak už název napovídá, je zodpovědný za načtení struktury mapy webu z trvalého úložiště a jeho vytvoření v paměti. GetRootNodeCore
vrátí kořenový uzel v mapě webu.
Než webová aplikace může použít zprostředkovatele mapy webu, musí být zaregistrovaná v konfiguraci aplikace. Ve výchozím nastavení XmlSiteMapProvider
je třída registrována pomocí názvu AspNetXmlSiteMapProvider
. Pokud chcete zaregistrovat další zprostředkovatele mapy webu, přidejte následující kód do Web.config
:
<configuration>
<system.web>
...
<siteMap defaultProvider="defaultProviderName">
<providers>
<add name="name" type="type" />
</providers>
</siteMap>
</system.web>
</configuration>
Hodnota názvu přiřadí zprostředkovateli čitelný název člověka, zatímco typ určuje plně kvalifikovaný název typu poskytovatele mapy webu. Po vytvoření vlastního poskytovatele mapy webu prozkoumáme konkrétní hodnoty pro název a typ v kroku 7.
Třída zprostředkovatele mapy webu je vytvořena při prvním přístupu z SiteMap
třídy a zůstává v paměti po celou dobu životnosti webové aplikace. Vzhledem k tomu, že existuje pouze jedna instance zprostředkovatele mapy webu, který může být vyvolán z více souběžných návštěvníků webu, je nezbytné, aby metody poskytovatele byly bezpečné pro přístup z více vláken.
Z důvodů výkonu a škálovatelnosti je důležité uložit strukturu mapy webu v paměti do mezipaměti a vrátit tuto strukturu uloženou v mezipaměti, místo aby se znovu vytvořila při BuildSiteMap
každém vyvolání metody. BuildSiteMap
v závislosti na ovládacích prvcích navigace, které se používají na stránce, a hloubky struktury mapy webu může být volána několikrát na každý uživatel požadavek na stránku. Pokud v každém případě neupamějíme strukturu mapy webu do BuildSiteMap
mezipaměti, při každém vyvolání bychom museli znovu načíst informace o produktu a kategorii z architektury (což by vedlo k dotazu na databázi). Jak jsme si probrali v předchozích kurzech ukládání do mezipaměti, můžou se data uložená v mezipaměti stát zastaralou. K tomu můžeme použít vypršení časového limitu nebo vypršení platnosti založeného na mezipaměti SQL.
Poznámka:
Zprostředkovatel mapy webu může volitelně přepsat metoduInitialize
. Initialize
je vyvolána při prvním vytvoření instance zprostředkovatele mapy webu a je předán všechny vlastní atributy přiřazené zprostředkovateli v Web.config
elementu <add>
jako: <add name="name" type="type" customAttribute="value" />
. Je užitečné, pokud chcete povolit vývojáři stránky zadat různá nastavení související s poskytovatelem mapy webu, aniž byste museli upravovat kód zprostředkovatele. Pokud bychom například četli data o kategoriích a produktech přímo z databáze, a ne prostřednictvím architektury, měli bychom chtít, aby vývojář stránky zadal databázi připojovací řetězec místo Web.config
použití pevně zakódované hodnoty v kódu zprostředkovatele. Vlastní zprostředkovatel mapy webu, který vytvoříme v kroku 6, tuto Initialize
metodu nepřepíše. Příklad použití Initialize
této metody najdete v článku o ukládání map webu v SQL Serveru od Jeffa Prosise.
Krok 6: Vytvoření vlastního zprostředkovatele mapy webu
Abychom vytvořili vlastního zprostředkovatele mapy webu, který sestaví mapu webu z kategorií a produktů v databázi Northwind, musíme vytvořit třídu, která rozšiřuje StaticSiteMapProvider
. V kroku 1 jsem vás požádal, abyste do složky přidali CustomProviders
složku App_Code
– přidejte do této složky novou třídu s názvem NorthwindSiteMapProvider
. Do třídy přidejte následující kód NorthwindSiteMapProvider
:
Imports System.Web
Imports System.Web.Caching
Public Class NorthwindSiteMapProvider
Inherits StaticSiteMapProvider
Private ReadOnly siteMapLock As New Object()
Private root As SiteMapNode = Nothing
Public Const CacheDependencyKey As String = "NorthwindSiteMapProviderCacheDependency"
Public Overrides Function BuildSiteMap() As System.Web.SiteMapNode
' Use a lock to make this method thread-safe
SyncLock siteMapLock
' First, see if we already have constructed the
' rootNode. If so, return it...
If root IsNot Nothing Then
Return root
End If
' We need to build the site map!
' Clear out the current site map structure
MyBase.Clear()
' Get the categories and products information from the database
Dim productsAPI As New ProductsBLL()
Dim products As Northwind.ProductsDataTable = productsAPI.GetProducts()
' Create the root SiteMapNode
root = New SiteMapNode( _
Me, "root", "~/SiteMapProvider/Default.aspx", "All Categories")
AddNode(root)
' Create SiteMapNodes for the categories and products
For Each product As Northwind.ProductsRow In products
' Add a new category SiteMapNode, if needed
Dim categoryKey, categoryName As String
Dim createUrlForCategoryNode As Boolean = True
If product.IsCategoryIDNull() Then
categoryKey = "Category:None"
categoryName = "None"
createUrlForCategoryNode = False
Else
categoryKey = String.Concat("Category:", product.CategoryID)
categoryName = product.CategoryName
End If
Dim categoryNode As SiteMapNode = FindSiteMapNodeFromKey(categoryKey)
' Add the category SiteMapNode if it does not exist
If categoryNode Is Nothing Then
Dim productsByCategoryUrl As String = String.Empty
If createUrlForCategoryNode Then
productsByCategoryUrl = _
"~/SiteMapProvider/ProductsByCategory.aspx?CategoryID=" & _
product.CategoryID
End If
categoryNode = New SiteMapNode _
(Me, categoryKey, productsByCategoryUrl, categoryName)
AddNode(categoryNode, root)
End If
' Add the product SiteMapNode
Dim productUrl As String = _
"~/SiteMapProvider/ProductDetails.aspx?ProductID=" & _
product.ProductID
Dim productNode As New SiteMapNode _
(Me, String.Concat("Product:", product.ProductID), _
productUrl, product.ProductName)
AddNode(productNode, categoryNode)
Next
' Add a "dummy" item to the cache using a SqlCacheDependency
' on the Products and Categories tables
Dim productsTableDependency As New _
System.Web.Caching.SqlCacheDependency("NorthwindDB", "Products")
Dim categoriesTableDependency As New _
System.Web.Caching.SqlCacheDependency("NorthwindDB", "Categories")
' Create an AggregateCacheDependency
Dim aggregateDependencies As New System.Web.Caching.AggregateCacheDependency()
aggregateDependencies.Add(productsTableDependency, categoriesTableDependency)
' Add the item to the cache specifying a callback function
HttpRuntime.Cache.Insert( _
CacheDependencyKey, DateTime.Now, aggregateDependencies, _
Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, _
CacheItemPriority.Normal, AddressOf OnSiteMapChanged)
' Finally, return the root node
Return root
End SyncLock
End Function
Protected Overrides Function GetRootNodeCore() As System.Web.SiteMapNode
Return BuildSiteMap()
End Function
Protected Sub OnSiteMapChanged _
(key As String, value As Object, reason As CacheItemRemovedReason)
SyncLock siteMapLock
If String.Compare(key, CacheDependencyKey) = 0 Then
' Refresh the site map
root = Nothing
End If
End SyncLock
End Sub
Public ReadOnly Property CachedDate() As Nullable(Of DateTime)
Get
Dim value As Object = HttpRuntime.Cache(CacheDependencyKey)
If value Is Nothing OrElse Not TypeOf value Is Nullable(Of DateTime) Then
Return Nothing
Else
Return CType(value, Nullable(Of DateTime))
End If
End Get
End Property
End Class
Začněme zkoumáním této metody třídyBuildSiteMap
, která začíná příkazemlock
. Příkaz lock
umožňuje zadat pouze jedno vlákno najednou, čímž serializuje přístup ke svému kódu a brání dvěma souběžným vlákenm v krokování mezi sebou s toky.
Proměnná root
na úrovni SiteMapNode
třídy slouží k ukládání struktury mapy webu do mezipaměti. Když se mapa webu vytvoří poprvé nebo poprvé po úpravě podkladových dat, root
vytvoří Nothing
se struktura mapy webu. Kořenový uzel mapy webu je přiřazen root
během procesu vytváření tak, aby při příštím zavolání root
této metody nebyl Nothing
. Pokud root
tedy není Nothing
struktura mapy webu vrácena volajícímu, aniž by bylo nutné ji znovu vytvořit.
Pokud je Nothing
kořen, vytvoří se struktura mapy webu z informací o produktu a kategorii. Mapa webu je vytvořena vytvořením SiteMapNode
instancí a následným vytvořením hierarchie prostřednictvím volání StaticSiteMapProvider
metody třídy AddNode
. AddNode
provádí interní účetnictví a ukládá seřazené SiteMapNode
instance do .Hashtable
Než začneme vytvářet hierarchii, začneme voláním Clear
metody, která vymaže prvky z interního Hashtable
. Dále se ProductsBLL
metoda třídy s GetProducts
a výsledná ProductsDataTable
metoda ukládají v místních proměnných.
Konstrukce mapy webu začíná vytvořením kořenového uzlu a jeho přiřazením .root
Přetížení konstruktoru použitého SiteMapNode
zde a v tomto případě BuildSiteMap
se předává následující informace:
- Odkaz na zprostředkovatele mapy webu (
Me
). Key
SSiteMapNode
. Tato požadovaná hodnota musí být pro každouSiteMapNode
hodnotu jedinečná .Url
SSiteMapNode
.Url
je nepovinný, ale pokud je zadaná, musí být každáSiteMapNode
Url
hodnota jedinečná.- Jedná se o
SiteMapNode
sTitle
, který je povinný.
Volání AddNode(root)
metody přidá SiteMapNode
root
do mapy webu jako kořen. V dalším kroku se vyčíslí každý ProductRow
z nich ProductsDataTable
. Pokud již existuje SiteMapNode
kategorie aktuálního produktu, odkazuje se na ni. V opačném případě se vytvoří nová SiteMapNode
kategorie a přidá se jako podřízený volání SiteMapNode``root
metody AddNode(categoryNode, root)
. Po nalezení nebo vytvoření SiteMapNode
příslušného uzlu kategorie SiteMapNode
se vytvoří pro aktuální produkt a přidá se jako podřízený uzel kategorie SiteMapNode
prostřednictvím AddNode(productNode, categoryNode)
. Všimněte si, že hodnota vlastnosti kategorie SiteMapNode
Url
je ~/SiteMapProvider/ProductsByCategory.aspx?CategoryID=categoryID
v době, kdy je vlastnost produktu Url
SiteMapNode
přiřazena ~/SiteMapNode/ProductDetails.aspx?ProductID=productID
.
Poznámka:
Produkty, které mají hodnotu databáze NULL
pro své CategoryID
jsou seskupeny do kategorie SiteMapNode
, jejíž Title
vlastnost je nastavena na None a jehož Url
vlastnost je nastavena na prázdný řetězec. Rozhodl jsem se nastavit Url
prázdný řetězec, protože ProductBLL
metoda třídy GetProductsByCategory(categoryID)
v současné době nemá schopnost vrátit pouze ty produkty s NULL
CategoryID
hodnotou. Také jsem chtěl předvést, jak ovládací prvky navigace vykreslují SiteMapNode
, která nemá hodnotu pro jeho Url
vlastnost. Doporučuji vám rozšířit tento kurz tak, aby None SiteMapNode
s Url
vlastnost odkazuje na ProductsByCategory.aspx
, ale zobrazuje pouze produkty s NULL
CategoryID
hodnotami.
Po vytvoření mapy webu se do mezipaměti dat přidá libovolný objekt pomocí závislosti mezipaměti SQL na objektu Categories
a Products
tabulek AggregateCacheDependency
. Prozkoumali jsme použití závislostí mezipaměti SQL v předchozím kurzu pomocí závislostí mezipaměti SQL. Vlastní zprostředkovatel mapy webu však používá přetížení metody mezipaměti Insert
dat, kterou jsme zatím prozkoumali. Toto přetížení přijímá jako konečný vstupní parametr delegát, který je volán při odebrání objektu z mezipaměti. Konkrétně předáme novému CacheItemRemovedCallback
delegátu , který odkazuje na metodu OnSiteMapChanged
definovanou dále ve NorthwindSiteMapProvider
třídě.
Poznámka:
Reprezentace mapy webu v paměti se ukládá do mezipaměti prostřednictvím proměnné root
na úrovni třídy . Vzhledem k tomu, že existuje pouze jedna instance vlastní třídy zprostředkovatele mapy webu a protože tato instance je sdílena mezi všemi vlákny webové aplikace, tato proměnná třídy slouží jako mezipaměť. Metoda BuildSiteMap
také používá mezipaměť dat, ale pouze jako prostředek pro příjem oznámení, když se podkladová data databáze v Categories
tabulkách změní Products
. Všimněte si, že hodnota vložená do mezipaměti dat je pouze aktuální datum a čas. Skutečná data mapy webu se neuloží do mezipaměti dat.
Metoda BuildSiteMap
se dokončí vrácením kořenového uzlu mapy webu.
Zbývající metody jsou poměrně jednoduché. GetRootNodeCore
zodpovídá za vrácení kořenového uzlu. Vzhledem k tomu BuildSiteMap
, že vrátí kořen, GetRootNodeCore
jednoduše vrátí BuildSiteMap
návratovou hodnotu. Metoda OnSiteMapChanged
se nastaví root
zpět při Nothing
odebrání položky mezipaměti. Při zpětném Nothing
nastavení kořenového adresáře se při příštím BuildSiteMap
vyvolání struktury mapy webu znovu sestaví. CachedDate
Nakonec vrátí vlastnost hodnotu data a času uloženou v mezipaměti dat, pokud taková hodnota existuje. Tuto vlastnost může použít vývojář stránky k určení, kdy byla data mapy webu naposledy uložena v mezipaměti.
Krok 7: RegistraceNorthwindSiteMapProvider
Aby naše webová aplikace mohla používat NorthwindSiteMapProvider
poskytovatele mapy webu vytvořeného v kroku 6, musíme ji zaregistrovat v <siteMap>
části Web.config
. Konkrétně přidejte do elementu <system.web>
Web.config
následující kód:
<siteMap defaultProvider="AspNetXmlSiteMapProvider">
<providers>
<add name="Northwind" type="NorthwindSiteMapProvider" />
</providers>
</siteMap>
Tento kód dělá dvě věci: nejprve označuje, že předdefinovaný AspNetXmlSiteMapProvider
je výchozí zprostředkovatel mapy webu; druhý, zaregistruje vlastního zprostředkovatele mapy webu vytvořeného v kroku 6 s názvem Northwind.
Poznámka:
U zprostředkovatelů mapy webu umístěných ve složce aplikace App_Code
je hodnota type
atributu jednoduše název třídy. Případně mohl být vlastní zprostředkovatel mapy webu vytvořen v samostatném projektu knihovny tříd s kompilovaným sestavením umístěným v adresáři webové aplikace /Bin
. V takovém případě by hodnota atributu type
byla Obor názvů.ClassName, AssemblyName .
Po aktualizaci Web.config
si chvilku prohlédněte libovolnou stránku z kurzů v prohlížeči. Všimněte si, že navigační rozhraní vlevo stále zobrazuje oddíly a kurzy definované v Web.sitemap
. Je to proto, že jsme zůstali AspNetXmlSiteMapProvider
jako výchozí zprostředkovatel. Abychom mohli vytvořit prvek uživatelského rozhraní navigace, který používá NorthwindSiteMapProvider
, budeme muset explicitně určit, že by se měl použít poskytovatel mapy webu Northwind. V kroku 8 se dozvíme, jak toho dosáhnout.
Krok 8: Zobrazení informací o mapě webu pomocí vlastního zprostředkovatele mapy webu
S vlastním poskytovatelem mapy webu vytvořeným a zaregistrovaným v Web.config
, jsme připraveni přidat navigační ovládací prvky do Default.aspx
ProductsByCategory.aspx
složky a ProductDetails.aspx
stránky ve SiteMapProvider
složce. Začněte otevřením Default.aspx
stránky a přetažením SiteMapPath
ze sady nástrojů do Návrháře. Ovládací prvek SiteMapPath se nachází v části Navigace panelu nástrojů.
Obrázek 16: Přidání cesty SiteMapPath (Default.aspx
kliknutím zobrazíte obrázek v plné velikosti)
Ovládací prvek SiteMapPath zobrazí popis cesty označující umístění aktuální stránky v mapě webu. Do horní části stránky předlohy jsme přidali cestu SiteMapPath v kurzu Stránky předlohy a Navigace na webu.
Chvilku si tuto stránku prohlédněte v prohlížeči. SiteMapPath přidaný na obrázek 16 používá výchozího zprostředkovatele mapy webu, který načítá data z Web.sitemap
. Proto popis cesty zobrazuje > přizpůsobení mapy webu, stejně jako popis cesty v pravém horním rohu.
Obrázek 17: Popis cesty používá výchozího zprostředkovatele mapy webu (kliknutím zobrazíte obrázek v plné velikosti).
Pokud chcete mít SiteMapPath přidaný na obrázku 16, použijte vlastního zprostředkovatele mapy webu, který jsme vytvořili v kroku 6, nastavte jeho SiteMapProvider
vlastnost na Northwind, název, který jsme přiřadili k objektu NorthwindSiteMapProvider
in Web.config
. Návrhář bohužel nadále používá výchozího poskytovatele mapy webu, ale pokud stránku navštívíte v prohlížeči po provedení této změny vlastnosti, uvidíte, že popis cesty teď používá vlastního poskytovatele mapy webu.
Obrázek 18: Popis cesty teď používá vlastního zprostředkovatele NorthwindSiteMapProvider
mapy webu (kliknutím zobrazíte obrázek plné velikosti).
Ovládací prvek SiteMapPath zobrazí na stránkách více funkční uživatelské rozhraní ProductsByCategory.aspx
ProductDetails.aspx
. Přidat SiteMapPath na tyto stránky, nastavení SiteMapProvider
vlastnosti v obou northwind. Klikněte Default.aspx
na odkaz Zobrazit produkty pro nápoje a potom na odkaz Zobrazit podrobnosti pro Chai Čaj. Jak ukazuje obrázek 19, popis cesty zahrnuje aktuální část mapy webu (Chai Čaj) a její předky: Nápoje a Všechny kategorie .
Obrázek 19: Popis cesty teď používá vlastního zprostředkovatele NorthwindSiteMapProvider
mapy webu (kliknutím zobrazíte obrázek s plnou velikostí).
Další prvky uživatelského rozhraní navigace lze použít kromě SiteMapPath, například Menu a TreeView ovládací prvky. Položky Default.aspx
, ProductsByCategory.aspx
a ProductDetails.aspx
stránky ke stažení pro tento kurz, například všechny ovládací prvky nabídky (viz obrázek 20). Podrobnější informace o ovládacích prvcích navigace na navigačním panelu a systému mapy webu v ASP.NET 2.0 najdete v části ASP.NET 2.0 Sofistikované funkce navigace na webu a oddíl Using Site Navigation Controls (Používání ovládacích prvků navigace webu) v rychlých startech ASP.NET 2.0.
Obrázek 20: Ovládací prvek nabídky obsahuje seznam jednotlivých kategorií a produktů (kliknutím zobrazíte obrázek v plné velikosti).
Jak už bylo zmíněno dříve v tomto kurzu, struktura mapy webu je přístupná prostřednictvím kódu programu prostřednictvím SiteMap
třídy. Následující kód vrátí kořen SiteMapNode
výchozího zprostředkovatele:
Dim root As SiteMapNode = SiteMap.RootNode
AspNetXmlSiteMapProvider
Vzhledem k tomu, že je výchozím poskytovatelem naší aplikace, výše uvedený kód by vrátil kořenový uzel definovaný v Web.sitemap
. Pokud chcete odkazovat na jiného zprostředkovatele mapy webu než výchozí, použijte SiteMap
vlastnost třídyProviders
, například takto:
Dim root As SiteMapNode = SiteMap.Providers("name").RootNode
Kde název je název vlastního poskytovatele mapy webu (Northwind, pro naši webovou aplikaci).
Pokud chcete získat přístup k členu specifickému pro zprostředkovatele mapy webu, použijte SiteMap.Providers["name"]
k načtení instance zprostředkovatele a jeho přetypování na příslušný typ. Pokud chcete například zobrazit NorthwindSiteMapProvider
vlastnost ASP.NET CachedDate
stránky, použijte následující kód:
Dim customProvider As NorthwindSiteMapProvider = _
TryCast(SiteMap.Providers("Northwind"), NorthwindSiteMapProvider)
If customProvider IsNot Nothing Then
Dim lastCachedDate As Nullable(Of DateTime) = customProvider.CachedDate
If lastCachedDate.HasValue Then
SiteMapLastCachedDate.Text = _
"Site map cached on: " & lastCachedDate.Value.ToString()
Else
SiteMapLastCachedDate.Text = "The site map is being reconstructed!"
End If
End If
Poznámka:
Nezapomeňte otestovat funkci závislostí mezipaměti SQL. Po návštěvě oddílu Default.aspx
, ProductsByCategory.aspx
a ProductDetails.aspx
stránek přejděte na některý z kurzů v části Úpravy, Vložení a Odstranění a upravte název kategorie nebo produktu. Pak se vraťte na jednu ze stránek ve SiteMapProvider
složce. Za předpokladu, že pro mechanismus dotazování uplynul dostatek času, aby si poznamenal změnu podkladové databáze, měla by se mapa webu aktualizovat tak, aby zobrazovala název nového produktu nebo kategorie.
Shrnutí
ASP.NET 2.0 funkcí mapy webu zahrnuje SiteMap
třídu, řadu předdefinovaných navigačních webových ovládacích prvků a výchozího poskytovatele mapy webu, který očekává, že informace mapy webu se zachovají do souboru XML. Abychom mohli použít informace o mapě webu z nějakého jiného zdroje, například z databáze, architektury aplikace nebo vzdálené webové služby, potřebujeme vytvořit vlastního zprostředkovatele mapy webu. To zahrnuje vytvoření třídy, která je odvozena přímo nebo nepřímo z SiteMapProvider
třídy.
V tomto kurzu jsme viděli, jak vytvořit vlastního zprostředkovatele mapy webu, který na základě mapy webu na základě informací o produktu a kategoriích vyčíslených z architektury aplikace. Náš poskytovatel rozšířil StaticSiteMapProvider
třídu a zahrnoval vytvoření BuildSiteMap
metody, která načetla data, vytvořila hierarchii mapy webu a do mezipaměti výslednou strukturu v proměnné na úrovni třídy. Závislost mezipaměti SQL s funkcí zpětného volání jsme použili k zneplatnění struktury uložené v mezipaměti při úpravě podkladových Categories
dat nebo Products
dat.
Šťastné programování!
Další čtení
Další informace o tématech probíraných v tomto kurzu najdete v následujících zdrojích informací:
- Ukládání map webů na SQL Server a poskytovatele mapy webu SQL, na který jste čekali
- Sada nástrojů provider
- Sofistikované funkce navigace na webu ASP.NET 2.0
O autorovi
Scott Mitchell, autor sedmi knih ASP/ASP.NET a zakladatel 4GuysFromRolla.com, pracuje s webovými technologiemi Microsoftu od roku 1998. Scott pracuje jako nezávislý konzultant, trenér a spisovatel. Jeho nejnovější kniha je Sams Teach Yourself ASP.NET 2.0 za 24 hodin. Je dostupný na mitchell@4GuysFromRolla.comadrese . nebo prostřednictvím svého blogu, který lze najít na http://ScottOnWriting.NET.
Zvláštní díky
Tato série kurzů byla zkontrolována mnoha užitečnými recenzenty. Vedoucí hodnotící tohoto kurzu byli Dave Gardner, Zack Jones, Teresa Murphy a Bernadette Leigh. Chcete si projít nadcházející články MSDN? Pokud ano, zahoďte mi řádek na mitchell@4GuysFromRolla.com.