📄 xmlsitemapprovider.cs
字号:
SiteMapNode parentNode = (SiteMapNode)queue.Dequeue();
XmlNode xmlNode = (XmlNode)queue.Dequeue();
SiteMapNode node = null;
if (!_siteMapNodeName.Equals(xmlNode.Name)) {
throw new ConfigurationErrorsException(
SR.GetString(SR.XmlSiteMapProvider_Only_SiteMapNode_Allowed),
xmlNode);
}
string providerName = null;
SecUtility.GetAndRemoveNonEmptyStringAttribute(xmlNode, _providerAttribute, ref providerName);
// If the siteMapNode references another provider
if (providerName != null) {
node = GetNodeFromProvider(providerName);
// No other attributes or child nodes are allowed on a provider node.
SecUtility.CheckForUnrecognizedAttributes(xmlNode);
SecUtility.CheckForNonCommentChildNodes(xmlNode);
}
else {
string siteMapFile = null;
SecUtility.GetAndRemoveNonEmptyStringAttribute(xmlNode, _siteMapFileAttribute, ref siteMapFile);
if (siteMapFile != null) {
node = GetNodeFromSiteMapFile(xmlNode, siteMapFile);
}
else {
node = GetNodeFromXmlNode(xmlNode, queue);
}
}
AddNodeInternal(node, parentNode, xmlNode);
if (rootNode == null) {
rootNode = node;
}
}
}
protected virtual void Dispose(bool disposing) {
//if (_handler != null)
//{
// Debug.Assert(_filename != null);
// HttpRuntime.FileChangesMonitor.StopMonitoringFile(_filename, _handler);
//}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
private void EnsureChildSiteMapProviderUpToDate(SiteMapProvider childProvider) {
SiteMapNode oldNode = (SiteMapNode)ChildProviderTable[childProvider];
SiteMapNode newNode = ((XmlSiteMapProvider)childProvider).GetRootNodeCore();
if (newNode == null) {
throw new ProviderException(SR.GetString(SR.XmlSiteMapProvider_invalid_sitemapnode_returned, childProvider.Name));
}
// child providers have been updated.
if (!oldNode.Equals(newNode)) {
// If the child provider table has been updated, simply return null.
// This will happen when the current provider's sitemap file is changed or Clear() is called;
if (oldNode == null) {
return;
}
lock (_lock) {
oldNode = (SiteMapNode)ChildProviderTable[childProvider];
// If the child provider table has been updated, simply return null. See above.
if (oldNode == null) {
return;
}
newNode = ((XmlSiteMapProvider)childProvider).GetRootNodeCore();
if (newNode == null) {
throw new ProviderException(SR.GetString(SR.XmlSiteMapProvider_invalid_sitemapnode_returned, childProvider.Name));
}
if (!oldNode.Equals(newNode)) {
// If the current provider does not contain any nodes but one child provider
// ie. _siteMapNode == oldNode
// the oldNode needs to be removed from Url table and the new node will be added.
if (_siteMapNode.Equals(oldNode)) {
UrlTable.Remove(oldNode.Url);
KeyTable.Remove(oldNode.Key);
UrlTable.Add(newNode.Url, newNode);
KeyTable.Add(newNode.Key, newNode);
_siteMapNode = newNode;
}
// First find the parent node
SiteMapNode parent = (SiteMapNode)ParentNodeTable[oldNode];
// parent is null when the provider does not contain any static nodes, ie.
// it only contains definition to include one child provider.
if (parent != null) {
// Update the child nodes table
SiteMapNodeCollection list = (SiteMapNodeCollection)ChildNodeCollectionTable[parent];
// Add the newNode to where the oldNode is within parent node's collection.
int index = list.IndexOf(oldNode);
if (index != -1) {
list.Remove(oldNode);
list.Insert(index, newNode);
}
else {
list.Add(newNode);
}
// Update the parent table
ParentNodeTable[newNode] = parent;
ParentNodeTable.Remove(oldNode);
// Update the Url table
UrlTable.Remove(oldNode.Url);
KeyTable.Remove(oldNode.Key);
UrlTable.Add(newNode.Url, newNode);
KeyTable.Add(newNode.Key, newNode);
}
else {
// Notify the parent provider to update its child provider collection.
XmlSiteMapProvider provider = ParentProvider as XmlSiteMapProvider;
if (provider != null) {
provider.EnsureChildSiteMapProviderUpToDate(this);
}
}
// Update provider nodes;
ChildProviderTable[childProvider] = newNode;
_childProviderList = null;
}
}
}
}
// Returns sitemap node; Search recursively in child providers if not found.
public override SiteMapNode FindSiteMapNode(string rawUrl) {
SiteMapNode node = base.FindSiteMapNode(rawUrl);
if (node == null) {
foreach(SiteMapProvider provider in ChildProviderList) {
// First make sure the child provider is up-to-date.
EnsureChildSiteMapProviderUpToDate(provider);
node = provider.FindSiteMapNode(rawUrl);
if (node != null) {
return node;
}
}
}
return node;
}
// Returns sitemap node; Search recursively in child providers if not found.
public override SiteMapNode FindSiteMapNodeFromKey(string key) {
SiteMapNode node = base.FindSiteMapNodeFromKey(key);
if (node == null) {
foreach (SiteMapProvider provider in ChildProviderList) {
// First make sure the child provider is up-to-date.
EnsureChildSiteMapProviderUpToDate(provider);
node = provider.FindSiteMapNodeFromKey(key);
if (node != null) {
return node;
}
}
}
return node;
}
private XmlDocument GetConfigDocument() {
if (_document != null)
return _document;
if (!_initialized) {
throw new InvalidOperationException(
SR.GetString(SR.XmlSiteMapProvider_Not_Initialized));
}
// Do the error checking here
if (_virtualPath == null) {
throw new ArgumentException(
SR.GetString(SR.XmlSiteMapProvider_missing_siteMapFile, _siteMapFileAttribute));
}
if (!Path.GetExtension(_virtualPath).Equals(_xmlSiteMapFileExtension, StringComparison.OrdinalIgnoreCase)) {
throw new InvalidOperationException(
SR.GetString(SR.XmlSiteMapProvider_Invalid_Extension, _virtualPath));
}
// Ensure the appdomain virtualpath has proper trailing slash
_normalizedVirtualPath =
VirtualPathUtility.Combine(AppDomainAppVirtualPathWithTrailingSlash, _virtualPath);
// Make sure the file exists
CheckSiteMapFileExists();
_parentSiteMapFileCollection = new StringCollection();
XmlSiteMapProvider xmlParentProvider = ParentProvider as XmlSiteMapProvider;
if (xmlParentProvider != null && xmlParentProvider._parentSiteMapFileCollection != null) {
if (xmlParentProvider._parentSiteMapFileCollection.Contains(_normalizedVirtualPath)) {
throw new InvalidOperationException(
SR.GetString(SR.XmlSiteMapProvider_FileName_already_in_use, _virtualPath));
}
// Copy the sitemapfiles in used from parent provider to current provider.
foreach (string filename in xmlParentProvider._parentSiteMapFileCollection) {
_parentSiteMapFileCollection.Add(filename);
}
}
// Add current sitemap file to the collection
_parentSiteMapFileCollection.Add(_normalizedVirtualPath);
_filename = HostingEnvironment.MapPath(_normalizedVirtualPath);
if (!String.IsNullOrEmpty(_filename)) {
//_handler = new FileChangeEventHandler(this.OnConfigFileChange);
//HttpRuntime.FileChangesMonitor.StartMonitoringFile(_filename, _handler);
ResourceKey = (new FileInfo(_filename)).Name;
}
_document = new ConfigXmlDocument();
return _document;
}
private SiteMapNode GetNodeFromProvider(string providerName) {
SiteMapProvider provider = GetProviderFromName(providerName);
SiteMapNode node = null;
// Check infinite recursive sitemap files
if (provider is XmlSiteMapProvider) {
XmlSiteMapProvider xmlProvider = (XmlSiteMapProvider)provider;
StringCollection parentSiteMapFileCollection = new StringCollection();
if (_parentSiteMapFileCollection != null) {
foreach (string filename in _parentSiteMapFileCollection) {
parentSiteMapFileCollection.Add(filename);
}
}
// Make sure the provider is initialized before adding to the collection.
xmlProvider.BuildSiteMap();
parentSiteMapFileCollection.Add(_normalizedVirtualPath);
if (parentSiteMapFileCollection.Contains(xmlProvider._normalizedVirtualPath)) {
throw new InvalidOperationException(SR.GetString(SR.XmlSiteMapProvider_FileName_already_in_use, xmlProvider._virtualPath));
}
xmlProvider._parentSiteMapFileCollection = parentSiteMapFileCollection;
}
node = ((XmlSiteMapProvider)provider).GetRootNodeCore();
if (node == null) {
throw new InvalidOperationException(
SR.GetString(SR.XmlSiteMapProvider_invalid_GetRootNodeCore, ((ProviderBase)provider).Name));
}
ChildProviderTable.Add(provider, node);
_childProviderList = null;
provider.ParentProvider = this;
return node;
}
private SiteMapNode GetNodeFromSiteMapFile(XmlNode xmlNode, String siteMapFile) {
SiteMapNode node = null;
// For external sitemap files, its secuity setting is inherited from parent provider
bool secuityTrimmingEnabled = SecurityTrimmingEnabled;
SecUtility.GetAndRemoveBooleanAttribute(xmlNode, _securityTrimmingEnabledAttrName, ref secuityTrimmingEnabled);
// No other attributes or non-comment nodes are allowed on a siteMapFile node
SecUtility.CheckForUnrecognizedAttributes(xmlNode);
SecUtility.CheckForNonCommentChildNodes(xmlNode);
XmlSiteMapProvider childProvider = new XmlSiteMapProvider();
// siteMapFile was relative to the sitemap file where this xmlnode is defined, make it an application path.
siteMapFile = VirtualPathUtility.Combine(VirtualPathUtility.GetDirectory(_normalizedVirtualPath), siteMapFile);
childProvider.ParentProvider = this;
childProvider.Initialize(siteMapFile, secuityTrimmingEnabled);
childProvider.BuildSiteMap();
node = childProvider._siteMapNode;
ChildProviderTable.Add(childProvider, node);
_childProviderList = null;
return node;
}
private void HandleResourceAttribute(XmlNode xmlNode, ref NameValueCollection collection,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -