📄 xmlsitemapprovider.cs
字号:
//------------------------------------------------------------------------------
// <copyright file="XmlSiteMapProvider.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
/*
* XmlSiteMapProvider class definition
*
* Copyright (c) 2002 Microsoft Corporation
*/
namespace Microsoft.Samples {
using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Configuration;
using System.Configuration.Provider;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Resources;
using System.Security;
using System.Security.Permissions;
using System.Web.Compilation;
using System.Web.Configuration;
using System.Web.Hosting;
using System.Web;
using System.Web.UI;
using System.Web.Util;
using System.Xml;
// XmlMapProvider that generates sitemap tree from xml files
public class XmlSiteMapProvider : StaticSiteMapProvider, IDisposable {
private string _filename;
private String _virtualPath;
private String _normalizedVirtualPath;
private SiteMapNode _siteMapNode;
private XmlDocument _document;
private bool _initialized;
//private FileChangeEventHandler _handler;
private StringCollection _parentSiteMapFileCollection;
private const string _providerAttribute = "provider";
private const string _siteMapFileAttribute = "siteMapFile";
private const string _siteMapNodeName = "siteMapNode";
private const string _xmlSiteMapFileExtension = ".sitemap";
private const string _resourcePrefix = "$resources:";
private const String _securityTrimmingEnabledAttrName = "securityTrimmingEnabled";
private const int _resourcePrefixLength = 10;
private const char _resourceKeySeparator = ',';
private static readonly char[] _seperators = new char[] { ';', ',' };
private ArrayList _childProviderList;
// table containing mappings from child providers to their root nodes.
private Hashtable _childProviderTable;
public XmlSiteMapProvider() {
}
private ArrayList ChildProviderList {
get {
if (_childProviderList == null) {
lock (_lock) {
if (_childProviderList == null) {
_childProviderList = ArrayList.ReadOnly(new ArrayList(ChildProviderTable.Keys));
}
}
}
return _childProviderList;
}
}
private Hashtable ChildProviderTable {
get {
if (_childProviderTable == null) {
lock (_lock) {
if (_childProviderTable == null) {
_childProviderTable = new Hashtable();
}
}
}
return _childProviderTable;
}
}
public override SiteMapNode RootNode {
get {
BuildSiteMap();
return ReturnNodeIfAccessible(_siteMapNode);
}
}
protected override void AddNode(SiteMapNode node, SiteMapNode parentNode) {
if (node == null) {
throw new ArgumentNullException("node");
}
if (parentNode == null) {
throw new ArgumentNullException("parentNode");
}
SiteMapProvider ownerProvider = node.Provider;
SiteMapProvider parentOwnerProvider = parentNode.Provider;
if (ownerProvider != this) {
throw new ArgumentException(SR.GetString(SR.XmlSiteMapProvider_cannot_add_node, node.ToString()), "node");
}
if (parentOwnerProvider != this) {
throw new ArgumentException(SR.GetString(SR.XmlSiteMapProvider_cannot_add_node, parentNode.ToString()), "parentNode");
}
lock (_lock) {
// First remove it from its current location.
RemoveNode(node);
AddNodeInternal(node, parentNode, null);
}
}
private void AddNodeInternal(SiteMapNode node, SiteMapNode parentNode, XmlNode xmlNode) {
lock (_lock) {
String url = node.Url;
String key = node.Key;
bool isValidUrl = false;
// Only add the node to the url table if it's a static node.
if (!String.IsNullOrEmpty(url)) {
if (UrlTable[url] != null) {
if (xmlNode != null) {
throw new ConfigurationErrorsException(
SR.GetString(SR.XmlSiteMapProvider_Multiple_Nodes_With_Identical_Url, url),
xmlNode);
}
else {
throw new InvalidOperationException(SR.GetString(
SR.XmlSiteMapProvider_Multiple_Nodes_With_Identical_Url, url));
}
}
isValidUrl = true;
}
if (KeyTable.Contains(key)) {
if (xmlNode != null) {
throw new ConfigurationErrorsException(
SR.GetString(SR.XmlSiteMapProvider_Multiple_Nodes_With_Identical_Key, key),
xmlNode);
}
else {
throw new InvalidOperationException(
SR.GetString(SR.XmlSiteMapProvider_Multiple_Nodes_With_Identical_Key, key));
}
}
if (isValidUrl) {
UrlTable[url] = node;
}
KeyTable[key] = node;
// Add the new node into parentNode collection
if (parentNode != null) {
ParentNodeTable[node] = parentNode;
if (ChildNodeCollectionTable[parentNode] == null) {
ChildNodeCollectionTable[parentNode] = new SiteMapNodeCollection();
}
((SiteMapNodeCollection)ChildNodeCollectionTable[parentNode]).Add(node);
}
}
}
protected virtual void AddProvider(string providerName, SiteMapNode parentNode) {
if (parentNode == null) {
throw new ArgumentNullException("parentNode");
}
if (parentNode.Provider != this) {
throw new ArgumentException(SR.GetString(SR.XmlSiteMapProvider_cannot_add_node, parentNode.ToString()), "parentNode");
}
SiteMapNode node = GetNodeFromProvider(providerName);
AddNodeInternal(node, parentNode, null);
}
public override SiteMapNode BuildSiteMap() {
SiteMapNode tempNode = _siteMapNode;
// If siteMap is already constructed, simply returns it.
// Child providers will only be updated when the parent providers need to access them.
if (tempNode != null) {
return tempNode;
}
XmlDocument document = GetConfigDocument();
lock (_lock) {
if (_siteMapNode != null) {
return _siteMapNode;
}
Clear();
// Need to check if the sitemap file exists before opening it.
CheckSiteMapFileExists();
try {
using (Stream stream = HostingEnvironment.VirtualPathProvider.GetFile(_normalizedVirtualPath).Open()) {
XmlReader reader = new XmlTextReader(stream);
document.Load(reader);
}
}
catch (Exception e) {
throw new ConfigurationErrorsException(
SR.GetString(SR.XmlSiteMapProvider_Error_loading_Config_file, _virtualPath, e.Message), e);
}
XmlNode node = null;
foreach (XmlNode siteMapMode in document.ChildNodes) {
if (String.Equals(siteMapMode.Name, "siteMap", StringComparison.Ordinal)) {
node = siteMapMode;
break;
}
}
if (node == null)
throw new ConfigurationErrorsException(
SR.GetString(SR.XmlSiteMapProvider_Top_Element_Must_Be_SiteMap),
document);
bool enableLocalization = false;
SecUtility.GetAndRemoveBooleanAttribute(node, "enableLocalization", ref enableLocalization);
EnableLocalization = enableLocalization;
XmlNode topElement = null;
foreach (XmlNode subNode in node.ChildNodes) {
if (subNode.NodeType == XmlNodeType.Element) {
if (!_siteMapNodeName.Equals(subNode.Name)) {
throw new ConfigurationErrorsException(
SR.GetString(SR.XmlSiteMapProvider_Only_SiteMapNode_Allowed),
subNode);
}
if (topElement != null) {
throw new ConfigurationErrorsException(
SR.GetString(SR.XmlSiteMapProvider_Only_One_SiteMapNode_Required_At_Top),
subNode);
}
topElement = subNode;
}
}
if (topElement == null) {
throw new ConfigurationErrorsException(
SR.GetString(SR.XmlSiteMapProvider_Only_One_SiteMapNode_Required_At_Top),
node);
}
Queue queue = new Queue(50);
// The parentnode of the top node does not exist,
// simply add a null to satisfy the ConvertFromXmlNode condition.
queue.Enqueue(null);
queue.Enqueue(topElement);
_siteMapNode = ConvertFromXmlNode(queue);
return _siteMapNode;
}
}
private void CheckSiteMapFileExists() {
if (!HostingEnvironment.VirtualPathProvider.FileExists(_normalizedVirtualPath)) {
throw new InvalidOperationException(
SR.GetString(SR.XmlSiteMapProvider_FileName_does_not_exist, _virtualPath));
}
}
protected override void Clear() {
lock (_lock) {
ChildProviderTable.Clear();
_siteMapNode = null;
_childProviderList = null;
base.Clear();
}
}
// helper method to convert an XmlNode to a SiteMapNode
private SiteMapNode ConvertFromXmlNode(Queue queue) {
SiteMapNode rootNode = null;
while (true) {
if (queue.Count == 0) {
return rootNode;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -