Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
tarafından Scott Mitchell
ASP.NET 2.0'daki varsayılan site haritası sağlayıcısı, verilerini statik xml dosyasından alır. XML tabanlı sağlayıcı birçok küçük ve orta ölçekli Web sitesi için uygun olsa da, daha büyük Web uygulamaları daha dinamik bir site haritası gerektirir. Bu öğreticide, verilerini İş Mantığı Katmanı'ndan alan ve veritabanından veri alan özel bir site haritası sağlayıcısı oluşturacağız.
Giriş
ASP.NET 2.0 sn site haritası özelliği, sayfa geliştiricinin xml dosyası gibi kalıcı bir ortamda bir web uygulaması site haritası tanımlamasını sağlar. Tanımlandıktan sonra, site haritası verilerine SiteMap sınıf aracılığıyla System.Web ad alanı ve SiteMapPath, Menü ve TreeView denetimleri gibi çeşitli gezinti Web denetimleri ile programlama ile erişilebilir. Site haritası sistemi, farklı site haritası serileştirme uygulamalarının oluşturulabilmesi ve bir web uygulamasına takılabilmesi için sağlayıcı modelini kullanır. ASP.NET 2.0 ile birlikte gelen varsayılan site haritası sağlayıcısı, site eşleme yapısını bir XML dosyasında kalıcı hale döndürür.
Ana Sayfalar ve Site Gezintisi öğreticisine geri dönüp bu yapıyı içeren ve XML'sini her yeni öğretici bölümüyle güncelleştiren adlı Web.sitemap bir dosya oluşturduk.
Site haritasının yapısı bu öğreticiler gibi oldukça statikse, varsayılan XML tabanlı site haritası sağlayıcısı iyi çalışır. Ancak birçok senaryoda daha dinamik bir site haritası gereklidir. Şekil 1'de gösterilen ve her kategorinin ve ürünün web sitesinin yapısında bölümler olarak göründüğü site haritasını göz önünde bulundurun. Bu site haritasıyla, kök düğüme karşılık gelen web sayfasını ziyaret etmek tüm kategorileri listelese de, belirli bir kategorinin web sayfasını ziyaret etmek söz konusu kategorinin ürünlerini listeler ve belirli bir ürünün web sayfasını görüntülemek bu ürünün ayrıntılarını gösterir.
Şekil 1: Kategoriler ve Ürünler Site Haritasının Yapısını Oluşturur (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Bu kategori ve ürün tabanlı yapı dosyaya Web.sitemap sabit kodlanmış olsa da, bir kategori veya ürün her eklendiğinde, kaldırıldığında veya yeniden adlandırıldığında dosyanın güncelleştirilmesi gerekir. Sonuç olarak, yapısı veritabanından veya ideal olarak uygulama mimarisinin İş Mantığı Katmanı'ndan alınırsa site haritası bakımı büyük ölçüde basitleştirilir. Bu şekilde, ürünler ve kategoriler eklendikçe, yeniden adlandırıldıkça veya silindikçe, site haritası bu değişiklikleri yansıtacak şekilde otomatik olarak güncelleştirilir.
ASP.NET 2.0 s site haritası serileştirmesi sağlayıcı modelinin üzerinde oluşturulduğundan, verilerini veritabanı veya mimari gibi alternatif bir veri deposundan alan kendi özel site haritası sağlayıcımızı oluşturabiliriz. Bu öğreticide, verilerini BLL'den alan özel bir sağlayıcı oluşturacağız. Haydi başlayalım!
Not
Bu öğreticide oluşturulan özel site haritası sağlayıcısı, uygulamanın mimarisine ve veri modeline sıkı sıkıya bağlıdır. Jeff Prosise'in Site Haritalarını SQL Server'da Depolamak ve Beklediğiniz SQL Site Haritası Sağlayıcısı makaleleri, site haritası verilerini SQL Server'da depolamak için genelleştirilmiş bir yaklaşımı inceler.
1. Adım: Özel Site Haritası Sağlayıcısı Web Sayfaları Oluşturma
Özel site haritası sağlayıcısı oluşturmaya başlamadan önce bu öğretici için ihtiyacımız olan ASP.NET sayfalarını ekleyelim. adlı SiteMapProvideryeni bir klasör ekleyerek başlayın. Ardından, aşağıdaki ASP.NET sayfaları bu klasöre ekleyerek her sayfayı ana sayfayla ilişkilendirdiğinizden Site.master emin olun:
Default.aspxProductsByCategory.aspxProductDetails.aspx
Ayrıca klasöre bir CustomProviders alt klasör App_Code ekleyin.
Şekil 2: Site Haritası Provider-Related Dersleri için ASP.NET Sayfaları Ekleme
Bu bölüm için yalnızca bir öğretici olduğundan, bölümün öğreticilerini listelememiz gerekmez Default.aspx . Bunun yerine, Default.aspx kategorileri GridView denetiminde görüntüler. 2. Adımda bunu ele alacağız.
Ardından, sayfaya bir başvuru içerecek şekilde güncelleştirin Web.sitemapDefault.aspx . Özellikle, Önbelleğe Alma'nın <siteMapNode>ardından aşağıdaki işaretlemeyi ekleyin:
<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." />
güncelleştirdikten Web.sitemapsonra, öğreticiler web sitesini bir tarayıcı üzerinden görüntülemek için biraz bekleyin. Soldaki menü artık tek site haritası sağlayıcısı öğreticisi için bir öğe içeriyor.
Şekil 3: Site Haritası Artık Site Haritası Sağlayıcısı Öğreticisi için Bir Giriş Içeriyor
Bu öğreticinin ana odağı, özel bir site haritası sağlayıcısı oluşturma ve bir web uygulamasını bu sağlayıcıyı kullanacak şekilde yapılandırmayı göstermektir. Özellikle, Şekil 1'de gösterildiği gibi, her kategori ve ürün için bir düğümle birlikte kök düğüm içeren bir site haritası döndüren bir sağlayıcı oluşturacağız. Genel olarak, site haritasındaki her düğüm bir URL belirtebilir. Site haritamız için kök düğümün URL'si olur ~/SiteMapProvider/Default.aspxve bu url veritabanındaki tüm kategorileri listeler. Site haritasındaki her kategori düğümü, belirtilen ~/SiteMapProvider/ProductsByCategory.aspx?CategoryID=categoryID'yi gösteren bir URL'sine sahip olacak ve bu URL tüm ürünleri listeleyecektir. Son olarak, her ürün sitesi haritası düğümü, belirli ürün ayrıntılarını görüntüleyen öğesini işaret ~/SiteMapProvider/ProductDetails.aspx?ProductID=productIDeder.
Başlamak için , Default.aspxve ProductsByCategory.aspx sayfalarını oluşturmamız ProductDetails.aspxgerekir. Bu sayfalar sırasıyla Adım 2, 3 ve 4'te tamamlanır. Bu öğreticinin itici gücü site haritası sağlayıcılarına ait olduğundan ve geçmiş öğreticilerde bu tür çok sayfalı ana/ayrıntı raporları oluşturmayı ele aldığımızdan, 2 ile 4 arası adımlarda acele edeceğiz. Birden çok sayfaya yayılan ana/ayrıntı raporları oluşturma konusunda bir hatırlatmaya ihtiyacınız varsa, İki Sayfada Ana/Ayrıntı Filtreleme kılavuzuna geri dönün.
2. Adım: Kategori Listesi Görüntüleme
Klasöründeki sayfayı Default.aspx açın ve Toolbox'tan SiteMapProvider Bir GridView'ı Tasarımcı'ya sürükleyip olarak ayarlayınIDCategories. GridView'un akıllı etiketinden bunu adlı CategoriesDataSource yeni bir ObjectDataSource'a bağlayın ve sınıf CategoriesBLL yöntemini kullanarak GetCategories verilerini alacak şekilde yapılandırın. Bu GridView yalnızca kategorileri görüntülediğinden ve veri değiştirme özellikleri sağlamadığından, UPDATE, INSERT ve DELETE sekmelerindeki açılan listeleri (Yok) olarak ayarlayın.
Şekil 4: Yöntemi Kullanarak ObjectDataSource'un Kategorileri Döndürecek Şekilde Yapılandırılması GetCategories (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Şekil 5: UPDATE, INSERT ve DELETE Sekmelerindeki Drop-Down Listelerini (Yok) olarak ayarlayın (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Veri Kaynağını Yapılandırma sihirbazını tamamladıktan sonra Visual Studio , , CategoryID, CategoryNameDescriptionve NumberOfProductsiçin BrochurePathbir BoundField ekler. GridView'ı yalnızca ve BoundField'lerini barındıracak CategoryName şekilde düzenleyin ve BoundField özelliğini Description Category olarak güncelleştirinCategoryName.HeaderText
Ardından, bir HyperLinkField ekleyin ve en soldaki alan olacak şekilde konumlandırın.
DataNavigateUrlFields özelliğini olarak CategoryID ve DataNavigateUrlFormatString özelliğini olarak ~/SiteMapProvider/ProductsByCategory.aspx?CategoryID={0}ayarlayın.
Text özelliğini Ürünleri Görüntüle olarak ayarlayın.
Şekil 6: GridView'a Categories HyperLinkField ekleme
ObjectDataSource oluşturulduktan ve GridView alanlarını özelleştirdikten sonra, bildirim temelli işaretleme iki denetim aşağıdaki gibi görünür:
<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>
Şekil 7'de tarayıcı üzerinden görüntülendiğinde gösterilmektedir Default.aspx . Bir kategorinin Ürünleri Görüntüle bağlantısına ProductsByCategory.aspx?CategoryID=categoryIDtıkladığınızda, adım 3'te oluşturacağımız adresine gelirsiniz.
Şekil 7: Her Kategori, Ürünleri Görüntüle Bağlantısıyla Birlikte Listelenir (Tam boyutlu görüntüyü görüntülemek için tıklayın)
3. Adım: Seçili Kategorinin Ürünlerini Listeleme
Sayfayı ProductsByCategory.aspx açın ve adını vererek ProductsByCategorybir GridView ekleyin. Akıllı etiketinden GridView'ı adlı ProductsByCategoryDataSourceyeni bir ObjectDataSource'a bağlayın. ObjectDataSource'ı sınıf ProductsBLL yöntemini kullanacak GetProductsByCategoryID(categoryID) şekilde yapılandırın ve UPDATE, INSERT ve DELETE sekmelerinde açılan listeleri (Yok) olarak ayarlayın.
Şekil 8: Sınıf ProductsBLL Yöntemini kullanma GetProductsByCategoryID(categoryID) (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Veri Kaynağını Yapılandırma sihirbazının son adımında categoryID için parametre kaynağı istenir. Bu bilgiler querystring alanından CategoryIDgeçirildiğinden, açılan listeden QueryString'i seçin ve Şekil 9'da gösterildiği gibi QueryStringField metin kutusuna CategoryID girin. Sihirbazı tamamlamak için Son’a tıklayın.
Şekil 9: CategoryID Parametresi için Sorgu Dizesi Alanını Kullanma (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Sihirbazı tamamladıktan sonra Visual Studio, ürün veri alanları için GridView'a karşılık gelen BoundField'leri ve CheckBoxField'ı ekler. , ve ProductNameUnitPrice BoundFields dışında SupplierNametümünü kaldırın. Bu üç BoundFields HeaderText özelliğini sırasıyla Product, Price ve Supplier değerlerini okuyacak şekilde özelleştirin. BoundField'i UnitPrice para birimi olarak biçimlendirin.
Ardından bir HyperLinkField ekleyin ve en soldaki konuma taşıyın. Özelliğini Text Ayrıntıları Görüntüle, DataNavigateUrlFields özelliğini olarak ProductIDve DataNavigateUrlFormatString özelliğini olarak ~/SiteMapProvider/ProductDetails.aspx?ProductID={0}ayarlayın.
Şekil 10: ProductDetails.aspx işaret eden bir Ayrıntıları Görüntüle HyperLinkField ekleyin
Bu özelleştirmeleri yaptıktan sonra GridView ve ObjectDataSource bildirim temelli işaretlemesi aşağıdakine benzer olmalıdır:
<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>
Tarayıcı üzerinden görüntülemeye Default.aspx dönün ve İçecekler için Ürünleri Görüntüle bağlantısına tıklayın. Bu sizi ProductsByCategory.aspx?CategoryID=1, Northwind veritabanındaki İçecekler kategorisine ait ürünlerin adlarını, fiyatlarını ve tedarikçilerini görüntüleyen bölümüne götürür (bkz. Şekil 11). Kullanıcıları kategori listeleme sayfasına (Default.aspx) döndürmek için bir bağlantı ve seçili kategorinin adını ve açıklamasını görüntüleyen detailsview veya FormView denetimini içerecek şekilde bu sayfayı daha da geliştirebilirsiniz.
Şekil 11: İçecek Adları, Fiyatlar ve Tedarikçiler Görüntülenir (Tam boyutlu görüntüyü görüntülemek için tıklayın)
4. Adım: Ürün Ayrıntılarını Gösterme
Son sayfa olan ProductDetails.aspx, seçili ürün ayrıntılarını görüntüler. Araç Kutusundan DetailsView'ı açın ProductDetails.aspx ve Tasarımcı'ya sürükleyin. DetailsView s özelliğini olarak ID ayarlayın ve ve ProductInfo özellik değerlerini temizleyinHeight.Width Akıllı etiketinden DetailsView'ı adlı ProductDataSourceyeni bir ObjectDataSource'a bağlayın ve ObjectDataSource'un verilerini sınıfın ProductsBLLGetProductByProductID(productID) yönteminden çekecek şekilde yapılandırın. 2. ve 3. Adımlarda oluşturulan önceki web sayfalarında olduğu gibi, UPDATE, INSERT ve DELETE sekmelerindeki açılan listeleri (Yok) olarak ayarlayın.
Şekil 12: ObjectDataSource'un Yöntemini Kullanacak Şekilde Yapılandırılması GetProductByProductID(productID) (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Veri Kaynağını Yapılandırma sihirbazının son adımında productID parametresinin kaynağı istenir. Bu veriler querystring alanı ProductIDüzerinden geldiğinden, açılan listeyi QueryString ve QueryStringField metin kutusunu ProductID olarak ayarlayın. Son olarak, sihirbazı tamamlamak için Son düğmesine tıklayın.
Şekil 13: ProductID Parametresini Sorgu Dizesi Alanından Değerini ProductID Çekecek Şekilde Yapılandırma (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Veri Kaynağını Yapılandırma sihirbazını tamamladıktan sonra Visual Studio, ürün veri alanları için DetailsView'da karşılık gelen BoundField'leri ve bir CheckBoxField'ı oluşturur.
ProductID, SupplierIDve BoundField değerlerini kaldırın ve CategoryID kalan alanları uygun gördüğünüz şekilde yapılandırın. Birkaç estetik yapılandırmadan sonra DetailsView ve ObjectDataSource bildirim temelli işaretlemem aşağıdaki gibi görünüyordu:
<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>
Bu sayfayı test etmek için İçecekler kategorisi için Ürünleri Görüntüle'ye Default.aspx geri dönün ve tıklayın. İçecek ürünleri listesinden Chai Tea için Ayrıntıları Görüntüle bağlantısına tıklayın. Bu sizi ProductDetails.aspx?ProductID=1Chai Tea s ayrıntılarını gösteren adresine götürür (bkz. Şekil 14).
Şekil 14: Chai Tea s Supplier, Category, Price ve Diğer Bilgiler Görüntüleniyor (Tam boyutlu görüntüyü görüntülemek için tıklayın)
5. Adım: Site Haritası Sağlayıcısının İç Çalışmalarını Anlama
Site haritası, web sunucusunun belleğinde hiyerarşi oluşturan örneklerin SiteMapNode koleksiyonu olarak temsil edilir. Tam olarak bir kök olmalıdır, kök olmayan tüm düğümler tam olarak bir üst düğüme sahip olmalıdır ve tüm düğümler rastgele sayıda alt düğüme sahip olabilir. Her SiteMapNode nesne web sitesi yapısındaki bir bölümü temsil eder; bu bölümler genellikle buna karşılık gelen bir web sayfasına sahiptir. Sonuç olarak, sınıfın SiteMapNode temsil ettiği bölüm Title için bilgi sağlayan , Urlve Descriptiongibi SiteMapNodeözellikleri vardır. Ayrıca hiyerarşideki her Key bir özelliği ve bu hiyerarşiyi SiteMapNode, , ChildNodes, ParentNode, NextSiblingvb. oluşturmak için kullanılan özellikleri benzersiz olarak tanımlayan bir PreviousSibling özellik vardır.
Şekil 15'te Şekil 1'deki genel site haritası yapısı gösterilir, ancak uygulama ayrıntıları daha ayrıntılı olarak çizilir.
Şekil 15: Her SiteMapNode örneği, Title, Url, Key ve benzeri özelliklere sahiptir (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Site haritasına SiteMap sınıfı aracılığıyla System.Web ad alanında erişilebilir. Bu sınıf s RootNode özelliği, site eşlemesinin kök SiteMapNode örneğini döndürür; CurrentNode özelliği şu anda istenen sayfanın URL'si ile eşleşen öğesini döndürür SiteMapNodeUrl . Bu sınıf, ASP.NET 2.0 s gezinti Web denetimleri tarafından dahili olarak kullanılır.
Sınıf özelliklerine SiteMap erişildiğinde, site haritası yapısını kalıcı bir ortamdan belleğe seri hale getirmesi gerekir. Ancak, site haritası serileştirme mantığı sınıfına SiteMap sabit kodlanmaz. Bunun yerine, çalışma zamanında SiteMap sınıf, serileştirme için hangi site haritası sağlayıcısının kullanılacağını belirler. Varsayılan olarak, XmlSiteMapProvider düzgün biçimlendirilmiş bir XML dosyasından site haritasının yapısını okuyan sınıfı kullanılır. Ancak, biraz çalışmayla kendi özel site haritası sağlayıcımızı oluşturabiliriz.
Tüm site haritası sağlayıcıları, site haritası sağlayıcıları için gerekli temel yöntemleri ve özellikleri içeren, ancak uygulama ayrıntılarının çoğunu atlayan sınıfından türetilmelidirSiteMapProvider. İkinci sınıf olan StaticSiteMapProvider, sınıfını SiteMapProvider genişletir ve gerekli işlevselliğin daha sağlam bir uygulamasını içerir. dahili olarak, StaticSiteMapProvider site haritasının örneklerini içinde SiteMapNode depolar Hashtable ve gibi AddNode(child, parent)RemoveNode(siteMapNode),yöntemler sağlar ve Clear() iç öğesine s SiteMapNodeekleyip kaldırırHashtable.
XmlSiteMapProvider , 'den StaticSiteMapProvidertüretilir.
genişleten StaticSiteMapProviderbir özel site haritası sağlayıcısı oluştururken, geçersiz kılınması gereken iki soyut yöntem vardır: BuildSiteMap ve GetRootNodeCore.
BuildSiteMapadından da anlaşılacağı gibi, site haritası yapısını kalıcı depolamadan yüklemek ve bellekte oluşturmaktan sorumludur.
GetRootNodeCore , site haritasında kök düğümü döndürür.
Bir web uygulamasının site haritası sağlayıcısını kullanabilmesi için önce uygulamanın yapılandırmasına kaydedilmesi gerekir. Varsayılan olarak, XmlSiteMapProvider sınıfı adı AspNetXmlSiteMapProviderkullanılarak kaydedilir. Ek site haritası sağlayıcılarını kaydetmek için aşağıdaki işaretlemeyi öğesine Web.configekleyin:
<configuration>
<system.web>
...
<siteMap defaultProvider="defaultProviderName">
<providers>
<add name="name" type="type" />
</providers>
</siteMap>
</system.web>
</configuration>
Ad değeri sağlayıcıya insan tarafından okunabilir bir ad atarken tür, site haritası sağlayıcısının tam tür adını belirtir. Özel site haritası sağlayıcımızı oluşturduktan sonra 7. Adımda ad ve tür değerleri için somut değerleri keşfedeceğiz.
Site haritası sağlayıcı sınıfı, sınıfından ilk kez erişildiğinde SiteMap örneği oluşturulur ve web uygulamasının ömrü boyunca bellekte kalır. Site haritası sağlayıcısının birden çok eşzamanlı web sitesi ziyaretçisinden çağrılabilecek tek bir örneği olduğundan, sağlayıcı yöntemlerinin iş parçacığı açısından güvenli olması zorunludur.
Performans ve ölçeklenebilirlik nedenleriyle, bellek içi site eşleme yapısını önbelleğe alıp yöntemi her çağrıldığında yeniden oluşturmadan bu önbelleğe alınmış yapıyı BuildSiteMap döndürmemiz önemlidir.
BuildSiteMap sayfada kullanımda olan gezinti denetimlerine ve site haritası yapısının derinliğine bağlı olarak, kullanıcı başına sayfa isteği başına birkaç kez çağrılabilir. Her durumda, site haritası yapısını BuildSiteMap her çağrıldığında önbelleğe almazsak, mimariden ürün ve kategori bilgilerini yeniden almamız gerekir (bu da veritabanına sorgu yapılmasına neden olur). Önceki önbelleğe alma öğreticilerinde ele aldığımız gibi önbelleğe alınan veriler eskitilebilir. Bununla mücadele etmek için zaman veya SQL önbelleği bağımlılığı tabanlı süre sonu kullanabiliriz.
Not
Site haritası sağlayıcısı isteğe bağlı olarak yöntemini geçersiz kılabilirInitialize.
Initialize , site haritası sağlayıcısı ilk kez başlatıldığında çağrılır ve öğesinde Web.config<add> sağlayıcıya atanmış olan özel öznitelikler geçirilir: <add name="name" type="type" customAttribute="value" />. Bir sayfa geliştiricinin sağlayıcı kodunu değiştirmek zorunda kalmadan site haritası sağlayıcısıyla ilgili çeşitli ayarları belirtmesine izin vermek istiyorsanız kullanışlıdır. Örneğin, kategori ve ürün verilerini mimarinin aksine doğrudan veritabanından okuyor olsaydık, sağlayıcı kodunda sabit kodlanmış bir değer kullanmak yerine sayfa geliştiricisinin veritabanı bağlantı dizesi Web.config belirtmesine izin vermek isteyebiliriz. 6. Adımda oluşturacağımız özel site haritası sağlayıcısı bu Initialize yöntemi geçersiz kılmaz. yöntemini kullanma Initialize örneği için Jeff ProsiseStoring Site Maps in SQL Server makalesine bakın.
6. Adım: Özel Site Haritası Sağlayıcısı Oluşturma
Northwind veritabanındaki kategoriler ve ürünlerden site haritasını oluşturan özel bir site haritası sağlayıcısı oluşturmak için, öğesini genişleten StaticSiteMapProviderbir sınıf oluşturmamız gerekir. 1. Adımda, klasörüne bir CustomProviders klasör App_Code eklemenizi istedim- bu klasöre adlı NorthwindSiteMapProvideryeni bir sınıf ekleyin. Sınıfına NorthwindSiteMapProvider aşağıdaki kodu ekleyin:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.Caching;
public class NorthwindSiteMapProvider : StaticSiteMapProvider
{
private readonly object siteMapLock = new object();
private SiteMapNode root = null;
public const string CacheDependencyKey =
"NorthwindSiteMapProviderCacheDependency";
public override SiteMapNode BuildSiteMap()
{
// Use a lock to make this method thread-safe
lock (siteMapLock)
{
// First, see if we already have constructed the
// rootNode. If so, return it...
if (root != null)
return root;
// We need to build the site map!
// Clear out the current site map structure
base.Clear();
// Get the categories and products information from the database
ProductsBLL productsAPI = new ProductsBLL();
Northwind.ProductsDataTable products = productsAPI.GetProducts();
// Create the root SiteMapNode
root = new SiteMapNode(
this, "root", "~/SiteMapProvider/Default.aspx", "All Categories");
AddNode(root);
// Create SiteMapNodes for the categories and products
foreach (Northwind.ProductsRow product in products)
{
// Add a new category SiteMapNode, if needed
string categoryKey, categoryName;
bool createUrlForCategoryNode = true;
if (product.IsCategoryIDNull())
{
categoryKey = "Category:None";
categoryName = "None";
createUrlForCategoryNode = false;
}
else
{
categoryKey = string.Concat("Category:", product.CategoryID);
categoryName = product.CategoryName;
}
SiteMapNode categoryNode = FindSiteMapNodeFromKey(categoryKey);
// Add the category SiteMapNode if it does not exist
if (categoryNode == null)
{
string productsByCategoryUrl = string.Empty;
if (createUrlForCategoryNode)
productsByCategoryUrl =
"~/SiteMapProvider/ProductsByCategory.aspx?CategoryID="
+ product.CategoryID;
categoryNode = new SiteMapNode(
this, categoryKey, productsByCategoryUrl, categoryName);
AddNode(categoryNode, root);
}
// Add the product SiteMapNode
string productUrl =
"~/SiteMapProvider/ProductDetails.aspx?ProductID="
+ product.ProductID;
SiteMapNode productNode = new SiteMapNode(
this, string.Concat("Product:", product.ProductID),
productUrl, product.ProductName);
AddNode(productNode, categoryNode);
}
// Add a "dummy" item to the cache using a SqlCacheDependency
// on the Products and Categories tables
System.Web.Caching.SqlCacheDependency productsTableDependency =
new System.Web.Caching.SqlCacheDependency("NorthwindDB", "Products");
System.Web.Caching.SqlCacheDependency categoriesTableDependency =
new System.Web.Caching.SqlCacheDependency("NorthwindDB", "Categories");
// Create an AggregateCacheDependency
System.Web.Caching.AggregateCacheDependency aggregateDependencies =
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,
new CacheItemRemovedCallback(OnSiteMapChanged));
// Finally, return the root node
return root;
}
}
protected override SiteMapNode GetRootNodeCore()
{
return BuildSiteMap();
}
protected void OnSiteMapChanged(string key, object value, CacheItemRemovedReason reason)
{
lock (siteMapLock)
{
if (string.Compare(key, CacheDependencyKey) == 0)
{
// Refresh the site map
root = null;
}
}
}
public DateTime? CachedDate
{
get
{
return HttpRuntime.Cache[CacheDependencyKey] as DateTime?;
}
}
}
Bu sınıfın BuildSiteMap yöntemiyle, bir lock ifadesi ile başlayan kısmını keşfetmeye başlayalım.
lock deyimi bir kerede yalnızca bir iş parçacığının girmesine izin verir, böylece koduna erişimi seri hale getirerek iki eş zamanlı iş parçacığının birbirine adım atmasını engeller.
Sınıf düzeyi SiteMapNode değişkeni root , site eşleme yapısını önbelleğe almak için kullanılır. Site haritası ilk kez oluşturulduğunda veya temel alınan veriler değiştirildikten rootnull sonra ilk kez oluşturulur ve site haritası yapısı oluşturulur. Site haritasının kök düğümü, bu yöntemin bir sonraki çağrılışında olarak rootadlandırılmaması içinroot, null oluşturma işlemi sırasında atanır. Sonuç olarak, site haritası yapısı olmadığı root sürece null yeniden oluşturmak zorunda kalmadan çağırana döndürülür.
Kök ise null, site haritası yapısı ürün ve kategori bilgilerinden oluşturulur. Site haritası, örnekleri oluşturup SiteMapNode ardından sınıf StaticSiteMapProvider yöntemine yapılan çağrılar aracılığıyla hiyerarşiyi AddNode oluşturarak oluşturulur.
AddNode, çeşitli örnekleri bir SiteMapNodeiçinde depolayarak Hashtable iç muhasebeyi gerçekleştirir. Hiyerarşiyi oluşturmadan önce, öğesini iç Clearöğesinden temizleyen yöntemini çağırarak Hashtable başlayacağız. Ardından, ProductsBLL s sınıfı GetProducts yöntemi ve sonuçta elde ProductsDataTable edilenler yerel değişkenlerde depolanır.
Site haritasının yapısı, kök düğümü oluşturup öğesine rootatayarak başlar. Burada ve bu SiteMapNode işlem boyunca kullanılan s oluşturucununBuildSiteMap aşırı yüklemesi aşağıdaki bilgiler geçirilir:
- Site haritası sağlayıcısına (
this) bir başvuru. - s
SiteMapNodeKey. Bu gerekli değer herSiteMapNodeiçin benzersiz olmalıdır. - s
SiteMapNodeUrl.Urlisteğe bağlıdır, ancak sağlanırsa herSiteMapNodedeğerinUrlbenzersiz olması gerekir. -
SiteMapNodeGerekli olan sTitle.
yöntem AddNode(root) çağrısı, SiteMapNoderoot öğesini kök olarak site haritasına ekler. Ardından içindeki her ProductRowProductsDataTable biri numaralandırılır. Geçerli ürün kategorisi için zaten bir SiteMapNode varsa, buna başvurulur. Aksi takdirde, yöntem çağrısı aracılığıyla kategorisi için yeni SiteMapNode bir oluşturulur ve öğesinin SiteMapNode``rootAddNode(categoryNode, root) alt öğesi olarak eklenir. Uygun kategori SiteMapNode düğümü bulunduktan veya oluşturulduktan sonra, geçerli ürün için bir SiteMapNode oluşturulur ve aracılığıyla SiteMapNodekategorinin AddNode(productNode, categoryNode) alt öğesi olarak eklenir. Kategorinin SiteMapNodeUrl özellik değerinin, ürün ~/SiteMapProvider/ProductsByCategory.aspx?CategoryID=categoryIDSiteMapNode özelliği atanırken Urlolduğuna ~/SiteMapNode/ProductDetails.aspx?ProductID=productID dikkat edin.
Not
Bunlar NULL için veritabanı CategoryID değerine sahip olan ürünler, özelliği Yok olarak ayarlanmış ve SiteMapNode özelliği boş bir dize olarak ayarlanmış bir kategori TitleUrl altında gruplandırılır. Sınıfın UrlProductBLL yöntemi şu anda yalnızca bir değere sahip olan ürünleri döndürme özelliğinden yoksun olduğundan boş bir GetProductsByCategory(categoryID)NULL dizeye ayarlamaya CategoryID karar verdim. Ayrıca, gezinti denetimlerinin özelliği için SiteMapNode bir değeri olmayan bir Url öğesini nasıl işlendiğini göstermek istedim. None SiteMapNode s Url özelliğinin yalnızca değerleri olan ProductsByCategory.aspxNULL ürünleri görüntülemesi için CategoryIDbu öğreticiyi genişletmenizi tavsiye ederim.
Site haritası oluşturulduktan sonra, bir nesne aracılığıyla ve Categories tablolarında SQL önbellek bağımlılığı kullanılarak veri önbelleğine Products rastgele bir AggregateCacheDependency nesne eklenir. Önceki öğreticide SQL Önbellek Bağımlılıklarını Kullanma öğreticisinde SQL önbellek bağımlılıklarını kullanmayı keşfettik. Ancak özel site haritası sağlayıcısı henüz araştırmadığımız veri önbelleği Insert yönteminin aşırı yüklemesini kullanır. Bu aşırı yükleme, nesne önbellekten kaldırıldığında çağrılan bir temsilcinin son giriş parametresi olarak kabul eder. Özellikle, CacheItemRemovedCallback yeni bir temsilci, OnSiteMapChanged sınıfında daha aşağıda tanımlanan NorthwindSiteMapProvider yöntemine işaret eder.
Not
Site eşlemesinin bellek içi gösterimi sınıf düzeyi değişkeni rootaracılığıyla önbelleğe alınır. Özel site haritası sağlayıcı sınıfının yalnızca bir örneği olduğundan ve bu örnek web uygulamasındaki tüm iş parçacıkları arasında paylaşıldığından, bu sınıf değişkeni önbellek görevi görür.
BuildSiteMap yöntemi veri önbelleğini de kullanır, ancak yalnızca veya Categories tablolarındaki temel veritabanı verileri değiştiğinde Products bildirim almak için bir araç olarak kullanılır. Veri önbelleğine koyulan değerin yalnızca geçerli tarih ve saat olduğunu unutmayın. Gerçek site haritası verileri veri önbelleğine yerleştirilmemiştir .
yöntemi, BuildSiteMap site haritasının kök düğümünü döndürerek tamamlar.
Kalan yöntemler oldukça basittir.
GetRootNodeCore kök düğümü döndürmekten sorumludur. Kök BuildSiteMap döndürdüğünden, GetRootNodeCore yalnızca s dönüş değerini döndürür BuildSiteMap .
OnSiteMapChanged yöntemi, önbellek öğesinin ne zaman kaldırılacağına root geri dönernull. Kök yeniden olarak nullayarlandığında, bir sonraki çağrıda BuildSiteMap site haritası yapısı yeniden oluşturulur. Son olarak özelliği, CachedDate böyle bir değer varsa veri önbelleğinde depolanan tarih ve saat değerini döndürür. Bu özellik, site haritası verilerinin en son ne zaman önbelleğe alındığını belirlemek için bir sayfa geliştiricisi tarafından kullanılabilir.
7. Adım:NorthwindSiteMapProvider
Web uygulamamızın 6. Adımda oluşturulan site haritası sağlayıcısını kullanabilmesi NorthwindSiteMapProvider için bu siteyi <siteMap> bölümüne Web.configkaydetmemiz gerekir. Özellikle, öğesinde aşağıdaki işaretlemeyi <system.web>Web.configekleyin:
<siteMap defaultProvider="AspNetXmlSiteMapProvider">
<providers>
<add name="Northwind" type="NorthwindSiteMapProvider" />
</providers>
</siteMap>
Bu işaretleme iki şey yapar: birincisi, yerleşikin AspNetXmlSiteMapProvider varsayılan site haritası sağlayıcısı olduğunu gösterir; ikincisi, 6. Adımda oluşturulan özel site haritası sağlayıcısını insan dostu Northwind adıyla kaydeder.
Not
Uygulamanın App_Code klasöründe bulunan site haritası sağlayıcıları için özniteliğin type değeri yalnızca sınıf adıdır. Alternatif olarak, özel site haritası sağlayıcısı, derlenmiş derleme web uygulamasının /Bin dizinine yerleştirilmiş ayrı bir Sınıf Kitaplığı projesinde oluşturulmuş olabilir. Bu durumda öznitelik type değeri Ad Alanı olacaktır.ClassName, AssemblyName .
güncelleştirdikten Web.configsonra, öğreticilerdeki herhangi bir sayfayı bir tarayıcıda görüntülemek için biraz bekleyin. Sol taraftaki gezinti arabiriminin içinde tanımlanan Web.sitemapbölümleri ve öğreticileri yine de gösterdiğini unutmayın. Bunun nedeni varsayılan sağlayıcı olarak ayrılmamızdır AspNetXmlSiteMapProvider . kullanan NorthwindSiteMapProviderbir gezinti kullanıcı arabirimi öğesi oluşturmak için Northwind site haritası sağlayıcısının kullanılması gerektiğini açıkça belirtmemiz gerekir. 8. Adımda bunu nasıl başaracağımızı göreceğiz.
8. Adım: Özel Site Haritası Sağlayıcısını Kullanarak Site Haritası Bilgilerini Görüntüleme
özel site haritası sağlayıcısı oluşturulduktan ve içinde Web.configkaydedildiyse, klasördeki , Default.aspxve ProductsByCategory.aspx sayfalarına ProductDetails.aspxgezinti denetimleri eklemeye SiteMapProvider hazırız. Başlangıç olarak sayfayı Default.aspx açın ve Araç Kutusu'ndan Tasarımcı'ya sürükleyin SiteMapPath . SiteMapPath denetimi, Araç Kutusu'nun Gezinti bölümünde bulunur.
Şekil 16: 'a Default.aspx SiteMapPath ekleme (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Site HaritasıPath denetimi, site haritasındaki geçerli sayfanın konumunu gösteren bir içerik haritası görüntüler. Ana Sayfalar ve Site Gezintisi öğreticisinde ana sayfanın en üstüne bir SiteMapPath ekledik.
Bu sayfayı bir tarayıcı üzerinden görüntülemek için biraz zaman ayırın. Şekil 16'da eklenen Site Haritası Yolu, varsayılan site haritası sağlayıcısını kullanır ve verilerini konumundan Web.sitemapçeker. Bu nedenle içerik haritası, tıpkı sağ üst köşedeki içerik haritasında olduğu gibi Site Haritasını Özelleştiren Giriş'i > gösterir.
Şekil 17: İz Takibi Varsayılan Site Haritası Sağlayıcısını Kullanır (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Şekil 16'da SiteMapPath'in eklenmesi için, Adım 6'da oluşturduğumuz özel site haritası sağlayıcısını SiteMapProvider kullanın, özelliğini içinde NorthwindSiteMapProviderkendisine atadığımız Web.config ad olan Northwind olarak ayarlayın. Ne yazık ki Tasarımcı varsayılan site haritası sağlayıcısını kullanmaya devam eder, ancak bu özellik değişikliğini yaptıktan sonra sayfayı bir tarayıcı üzerinden ziyaret ederseniz içerik haritasının artık özel site haritası sağlayıcısını kullandığını görürsünüz.
Şekil 18: Gezinti İzleri Artık Özel Site Haritası Sağlayıcısını Kullanıyor NorthwindSiteMapProvider (Tam boyutlu görüntüyü görüntülemek için tıklayın)
SiteMapPath denetimi ve ProductsByCategory.aspx sayfalarında daha işlevsel bir kullanıcı arabirimi ProductDetails.aspx görüntüler. Her ikisinde de özelliğini Northwind olarak ayarlayarak SiteMapProvider bu sayfalara bir SiteMapPath ekleyin. İçecekler Default.aspx için Ürünleri Görüntüle bağlantısına ve ardından Chai Tea için Ayrıntıları Görüntüle bağlantısına tıklayın. Şekil 19'da gösterildiği gibi içerik haritası geçerli site haritası bölümünü ( Chai Tea ) ve atalarını içerir: İçecekler ve Tüm Kategoriler .
Şekil 19: Gezinti Yolu Artık Özel Site Haritası Sağlayıcısını Kullanıyor NorthwindSiteMapProvider (Tam boyutlu görüntüyü görmek için tıklayın)
Menu ve TreeView denetimleri gibi SiteMapPath'e ek olarak diğer gezinti kullanıcı arabirimi öğeleri kullanılabilir.
Default.aspxÖrneğin, bu öğreticinin indirmesindeki , ProductsByCategory.aspxve ProductDetails.aspx sayfaları menü denetimlerini içerir (bkz. Şekil 20).
ASP.NET 2.0'daki gezinti denetimlerine ve site haritası sistemine daha ayrıntılı bir bakış için ASP.NET 2.0 Hızlı Başlangıçları'nın ASP.NET 2.0'ın Gelişmiş Site Gezinti Özellikleri ve Site Gezinti Denetimlerini Kullanma bölümüne bakın.
Şekil 20: Menü Denetimi Kategorilerin ve Ürünlerin Her Birini Listeler (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Bu öğreticide daha önce belirtildiği gibi, site haritası yapısına sınıf üzerinden SiteMap program aracılığıyla erişilebilir. Aşağıdaki kod varsayılan sağlayıcının kökünü SiteMapNode döndürür:
SiteMapNode root = SiteMap.RootNode;
AspNetXmlSiteMapProvider uygulamamız için varsayılan sağlayıcı olduğundan yukarıdaki kod içinde Web.sitemaptanımlanan kök düğümü döndürür. Varsayılan dışında bir site haritası sağlayıcısına başvurmak için aşağıdaki gibi sınıf s SiteMap kullanınProviders:
SiteMapNode root = SiteMap.Providers["name"].RootNode;
Burada ad , özel site haritası sağlayıcısının adıdır (Web uygulamamız için Northwind).
Site haritası sağlayıcısına özgü bir üyeye erişmek için öğesini kullanarak SiteMap.Providers["name"] sağlayıcı örneğini alın ve uygun türe yayınlayın. Örneğin, s NorthwindSiteMapProvider özelliğini bir ASP.NET sayfasında görüntülemek CachedDate için aşağıdaki kodu kullanın:
NorthwindSiteMapProvider customProvider =
SiteMap.Providers["Northwind"] as NorthwindSiteMapProvider;
if (customProvider != null)
{
DateTime? lastCachedDate = customProvider.CachedDate;
if (lastCachedDate != null)
LabelID.Text = "Site map cached on: " + lastCachedDate.Value.ToString();
else
LabelID.Text = "The site map is being reconstructed!";
}
Not
SQL önbellek bağımlılığı özelliğini test etmeye dikkat edin. , Default.aspxve sayfalarını ziyaret ettikten ProductsByCategory.aspxsonra Düzenleme, Ekleme ve ProductDetails.aspx Silme bölümündeki öğreticilerden birine gidin ve bir kategori veya ürünün adını düzenleyin. Ardından klasördeki sayfalardan SiteMapProvider birine dönün. Temel alınan veritabanındaki değişikliği not etmek için yoklama mekanizması için yeterli süre geçtiğini varsayarsak, site haritası yeni ürün veya kategori adını gösterecek şekilde güncelleştirilmelidir.
Özet
ASP.NET 2.0 sn site haritası özellikleri arasında bir SiteMap sınıf, bir dizi yerleşik gezinti Web denetimi ve site haritası bilgilerinin xml dosyasında kalıcı olmasını bekleyen varsayılan bir site haritası sağlayıcısı bulunur. Veritabanı, uygulama mimarisi veya uzak Web hizmeti gibi başka bir kaynaktan site haritası bilgilerini kullanmak için özel bir site haritası sağlayıcısı oluşturmamız gerekir. Bu, doğrudan veya dolaylı olarak sınıfından SiteMapProvider türetilen bir sınıf oluşturmayı içerir.
Bu öğreticide, uygulama mimarisinden kaynaklanan ürün ve kategori bilgilerine göre site haritasını temel alan özel bir site haritası sağlayıcısının nasıl oluşturulacağını gördük. Sağlayıcımız sınıfı genişletti StaticSiteMapProvider ve verileri alan, site haritası hiyerarşisini oluşturan ve sonuçta elde edilen yapıyı sınıf düzeyinde bir değişkende önbelleğe alan bir yöntem oluşturmayı BuildSiteMap gerektiriyordu. Temel alınan Categories veya Products veriler değiştirildiğinde önbelleğe alınan yapıyı geçersiz kılma amacıyla bir geri çağırma işleviyle sql önbellek bağımlılığı kullandık.
Mutlu Programlama!
Daha Fazla Bilgi
Bu öğreticide ele alınan konular hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın:
- Site Haritalarını SQL Server'da ve Beklediğiniz SQL Site Haritası Sağlayıcısında Depolama
- Sağlayıcı Araç Seti
- ASP.NET 2.0'ın Gelişmiş Site Gezinti Özellikleri
Yazar hakkında
Yedi ASP/ASP.NET kitabının yazarı ve 4GuysFromRolla.com kurucusu Scott Mitchell, 1998'den beri Microsoft Web teknolojileriyle çalışmaktadır. Scott bağımsız bir danışman, eğitmen ve yazar olarak çalışır. Son kitabı Sams Teach Yourself ASP.NET 24 Hours 2.0'dır. Ona adresinden mitchell@4GuysFromRolla.comulaşabilirsiniz.
Özel Teşekkürler
Bu öğretici serisi birçok yararlı gözden geçiren tarafından gözden geçirildi. Bu öğreticinin baş gözden geçirenleri Dave Gardner, Zack Jones, Teresa Murphy ve Bernadette Leigh oldu. Yaklaşan MSDN makalelerimi gözden geçirmek istiyor musunuz? Öyleyse, mitchell@4GuysFromRolla.com'a bir mesaj bırakın.