Code:
/ FXUpdate3074 / FXUpdate3074 / 1.1 / DEVDIV / depot / DevDiv / releases / whidbey / QFE / ndp / fx / src / xsp / System / Web / UI / WebControls / XmlDataSource.cs / 2 / XmlDataSource.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Web.UI.WebControls { using System; using System.Collections; using System.Collections.Specialized; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; using System.Globalization; using System.IO; using System.Security.Permissions; using System.Text; using System.Web; using System.Web.Hosting; using System.Web.Caching; using System.Web.UI; using System.Xml; using System.Xml.Xsl; using System.Web.Util; ////// Represents an XML file as both an IDataSource and an IHierarchicalDataSource. /// The XML data is retrieved either from a file specified by the DataFile property /// or by inline XML content in the Data property. /// [ DefaultEvent("Transforming"), DefaultProperty("DataFile"), Designer("System.Web.UI.Design.WebControls.XmlDataSourceDesigner, " + AssemblyRef.SystemDesign), ParseChildren(true), PersistChildren(false), ToolboxBitmap(typeof(XmlDataSource)), WebSysDescription(SR.XmlDataSource_Description), WebSysDisplayName(SR.XmlDataSource_DisplayName) ] [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] public class XmlDataSource : HierarchicalDataSourceControl, IDataSource, IListSource { private static readonly object EventTransforming = new object(); private const string DefaultViewName = "DefaultView"; private DataSourceCache _cache; private bool _cacheLookupDone; private bool _disallowChanges; private XsltArgumentList _transformArgumentList; private ICollection _viewNames; private XmlDocument _xmlDocument; private string _writeableDataFile; private string _data; private string _dataFile; private string _transform; private string _transformFile; private string _xPath; ////// Specifies the cache settings for this data source. /// private DataSourceCache Cache { get { if (_cache == null) { _cache = new DataSourceCache(); _cache.Enabled = true; } return _cache; } } ////// The duration, in seconds, of the expiration. The expiration policy is specified by the CacheExpirationPolicy property. /// [ DefaultValue(DataSourceCache.Infinite), TypeConverterAttribute(typeof(DataSourceCacheDurationConverter)), WebCategory("Cache"), WebSysDescription(SR.DataSourceCache_Duration), ] public virtual int CacheDuration { get { return Cache.Duration; } set { Cache.Duration = value; } } ////// The expiration policy of the cache. The duration for the expiration is specified by the CacheDuration property. /// [ DefaultValue(DataSourceCacheExpiry.Absolute), WebCategory("Cache"), WebSysDescription(SR.DataSourceCache_ExpirationPolicy), ] public virtual DataSourceCacheExpiry CacheExpirationPolicy { get { return Cache.ExpirationPolicy; } set { Cache.ExpirationPolicy = value; } } ////// Indicates an arbitrary cache key to make this cache entry depend on. This allows /// the user to further customize when this cache entry will expire. /// [ DefaultValue(""), WebCategory("Cache"), WebSysDescription(SR.DataSourceCache_KeyDependency), ] public virtual string CacheKeyDependency { get { return Cache.KeyDependency; } set { Cache.KeyDependency = value; } } ////// Inline XML content. /// [ DefaultValue(""), Editor("System.ComponentModel.Design.MultilineStringEditor," + AssemblyRef.SystemDesign, typeof(UITypeEditor)), PersistenceMode(PersistenceMode.InnerProperty), TypeConverter("System.ComponentModel.MultilineStringConverter," + AssemblyRef.System), WebCategory("Data"), WebSysDescription(SR.XmlDataSource_Data), ] public virtual string Data { get { if (_data == null) { return String.Empty; } return _data; } set { if (value != null) { value = value.Trim(); } if (Data != value) { if (_disallowChanges) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_CannotChangeWhileLoading, "Data", ID)); } _data = value; _xmlDocument = null; OnDataSourceChanged(EventArgs.Empty); } } } ////// Path to an XML file. /// [ DefaultValue(""), Editor("System.Web.UI.Design.XmlDataFileEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)), WebCategory("Data"), WebSysDescription(SR.XmlDataSource_DataFile), ] public virtual string DataFile { get { if (_dataFile == null) { return String.Empty; } return _dataFile; } set { if (DataFile != value) { if (_disallowChanges) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_CannotChangeWhileLoading, "DataFile", ID)); } _dataFile = value; _xmlDocument = null; _writeableDataFile = null; OnDataSourceChanged(EventArgs.Empty); } } } ////// Whether caching is enabled for this data source. /// [ DefaultValue(true), WebCategory("Cache"), WebSysDescription(SR.DataSourceCache_Enabled), ] public virtual bool EnableCaching { get { return Cache.Enabled; } set { Cache.Enabled = value; } } ////// Indicates whether the XML data can be modified. /// This is also used by XmlDataSourceView to determine whether CanDelete/Insert/Update are true. /// internal bool IsModifiable { get { return (String.IsNullOrEmpty(TransformFile) && String.IsNullOrEmpty(Transform) && !String.IsNullOrEmpty(WriteableDataFile)); } } ////// Inline XSL transform. /// [ DefaultValue(""), Editor("System.ComponentModel.Design.MultilineStringEditor," + AssemblyRef.SystemDesign, typeof(UITypeEditor)), PersistenceMode(PersistenceMode.InnerProperty), TypeConverter("System.ComponentModel.MultilineStringConverter," + AssemblyRef.System), WebCategory("Data"), WebSysDescription(SR.XmlDataSource_Transform), ] public virtual string Transform { get { if (_transform == null) { return String.Empty; } return _transform; } set { if (value != null) { value = value.Trim(); } if (Transform != value) { if (_disallowChanges) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_CannotChangeWhileLoading, "Transform", ID)); } _transform = value; _xmlDocument = null; OnDataSourceChanged(EventArgs.Empty); } } } ////// Arguments for the XSL transform. /// This should be populated in the Transforming event. /// [ Browsable(false), ] public virtual XsltArgumentList TransformArgumentList { get { return _transformArgumentList; } set { _transformArgumentList = value; } } ////// Path to an XSL transform file. /// [ DefaultValue(""), Editor("System.Web.UI.Design.XslTransformFileEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)), WebCategory("Data"), WebSysDescription(SR.XmlDataSource_TransformFile), ] public virtual string TransformFile { get { if (_transformFile == null) { return String.Empty; } return _transformFile; } set { if (TransformFile != value) { if (_disallowChanges) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_CannotChangeWhileLoading, "TransformFile", ID)); } _transformFile = value; _xmlDocument = null; OnDataSourceChanged(EventArgs.Empty); } } } ////// Gets a physical path of the data file that can be written to. /// The value is null if the path is not a writable path. /// private string WriteableDataFile { get { if (_writeableDataFile == null) { _writeableDataFile = GetWriteableDataFile(); } return _writeableDataFile; } } ////// Specifies an initial XPath that is applied to the XML data. /// [ DefaultValue(""), WebCategory("Data"), WebSysDescription(SR.XmlDataSource_XPath), ] public virtual string XPath { get { if (_xPath == null) { return String.Empty; } return _xPath; } set { if (XPath != value) { if (_disallowChanges) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_CannotChangeWhileLoading, "XPath", ID)); } _xPath = value; OnDataSourceChanged(EventArgs.Empty); } } } ////// Raised before the XSL transform is applied. /// [ WebCategory("Data"), WebSysDescription(SR.XmlDataSource_Transforming), ] public event EventHandler Transforming { add { Events.AddHandler(EventTransforming, value); } remove { Events.RemoveHandler(EventTransforming, value); } } ////// Creates a unique cache key for this data source's data. /// private string CreateCacheKey() { StringBuilder sb = new StringBuilder(CacheInternal.PrefixDataSourceControl, 1024); sb.Append(GetType().GetHashCode().ToString(CultureInfo.InvariantCulture)); sb.Append(CacheDuration.ToString(CultureInfo.InvariantCulture)); sb.Append(':'); sb.Append(((int)CacheExpirationPolicy).ToString(CultureInfo.InvariantCulture)); bool includeUniqueID = false; if (DataFile.Length > 0) { sb.Append(':'); sb.Append(DataFile); } else { if (Data.Length > 0) { includeUniqueID = true; } } if (TransformFile.Length > 0) { sb.Append(':'); sb.Append(TransformFile); } else { if (Transform.Length > 0) { includeUniqueID = true; } } if (includeUniqueID) { // If we don't have any paths, use the Page if (Page != null) { sb.Append(':'); sb.Append(Page.GetType().AssemblyQualifiedName); } sb.Append(':'); string uniqueID = UniqueID; if (String.IsNullOrEmpty(uniqueID)) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_NeedUniqueIDForCache)); } sb.Append(uniqueID); } return sb.ToString(); } ////// Returns a HierarchicalDataSourceView based on an XPath specified by viewPath. /// protected override HierarchicalDataSourceView GetHierarchicalView(string viewPath) { return new XmlHierarchicalDataSourceView(this, viewPath); } ////// Gets an XmlReader representing XML or XSL content, and optionally a cache /// dependency for that content. /// Supported paths are: Relative paths, physical paths, UNC paths, and HTTP URLs /// If a path is not provided, the content parameter is assumed to contain the /// actual content. /// If there is no data, null is returned. /// This method is fully compatible with Virtual Path Providers. /// private XmlReader GetReader(string path, string content, out CacheDependency cacheDependency) { // If a filename is specified, load from file. Otherwise load from inner content. if (path.Length != 0) { // First try to detect if it is an HTTP URL Uri uri; bool success = Uri.TryCreate(path, UriKind.Absolute, out uri); if (success) { if (uri.Scheme == Uri.UriSchemeHttp) { // Check for Web permissions for the URL we want if (!HttpRuntime.HasWebPermission(uri)) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_NoWebPermission, uri.PathAndQuery, ID)); } // Dependencies are not supported with HTTP URLs cacheDependency = null; // If it is an HTTP URL and we have permissions, get a reader return new XmlTextReader(path); } } // Now see what kind of file-based path it is VirtualPath virtualPath; string physicalPath; ResolvePhysicalOrVirtualPath(path, out virtualPath, out physicalPath); if (virtualPath != null && DesignMode) { // This exception should never be thrown - the designer always maps paths // before using the runtime control. throw new NotSupportedException(SR.GetString(SR.XmlDataSource_DesignTimeRelativePathsNotSupported, ID)); } Stream dataStream = OpenFileAndGetDependency(virtualPath, physicalPath, out cacheDependency); return new XmlTextReader(dataStream); } else { // Dependencies are not supported with inline content cacheDependency = null; content = content.Trim(); if (content.Length == 0) { return null; } else { return new XmlTextReader(new StringReader(content)); } } } ////// Gets a path to a writeable file where we can save data to. /// The return value is null if a writeable path cannot be found. /// private string GetWriteableDataFile() { if (DataFile.Length != 0) { // First try to detect if it is an HTTP URL Uri uri; bool success = Uri.TryCreate(DataFile, UriKind.Absolute, out uri); if (success) { if (uri.Scheme == Uri.UriSchemeHttp) { // Cannot write to HTTP URLs return null; } } if (HostingEnvironment.UsingMapPathBasedVirtualPathProvider) { // Now see what kind of file-based path it is VirtualPath virtualPath; string physicalPath; ResolvePhysicalOrVirtualPath(DataFile, out virtualPath, out physicalPath); if (physicalPath == null) { physicalPath = virtualPath.MapPathInternal(this.TemplateControlVirtualDirectory, true /*allowCrossAppMapping*/); } return physicalPath; } else { // File is coming from a custom virtual path provider, and there is no support for writing return null; } } else { // Data is specified using Data property, so it is not writeable return null; } } ////// Returns the XmlDocument representing the XML data. /// If necessary, the XML data will be reloaded along with the transform, if available. /// public XmlDocument GetXmlDocument() { string cacheKey = null; if (!_cacheLookupDone && Cache.Enabled) { // If caching is enabled, attempt to load from cache. cacheKey = CreateCacheKey(); _xmlDocument = Cache.LoadDataFromCache(cacheKey) as XmlDocument; _cacheLookupDone = true; } if (_xmlDocument == null) { // Load up the data _xmlDocument = new XmlDocument(); CacheDependency transformCacheDependency; CacheDependency dataCacheDependency; PopulateXmlDocument(_xmlDocument, out dataCacheDependency, out transformCacheDependency); if (cacheKey != null) { Debug.Assert(Cache.Enabled); // If caching is enabled, save the XmlDocument to cache. CacheDependency fileDependency; if (dataCacheDependency != null) { if (transformCacheDependency != null) { // We have both a data file as well as a transform file dependency AggregateCacheDependency aggregateDependency = new AggregateCacheDependency(); aggregateDependency.Add(dataCacheDependency, transformCacheDependency); fileDependency = aggregateDependency; } else { // We only have a data file dependency fileDependency = dataCacheDependency; } } else { // We have at most only a transform file dependency (or no dependency at all) fileDependency = transformCacheDependency; } Cache.SaveDataToCache(cacheKey, _xmlDocument, fileDependency); } } return _xmlDocument; } ////// Populates an XmlDocument with the appropriate XML data, including applying transforms. /// private void PopulateXmlDocument(XmlDocument document, out CacheDependency dataCacheDependency, out CacheDependency transformCacheDependency) { XmlReader transformReader = null; XmlReader dataReader = null; XmlReader tempDataReader = null; try { // Don't allow changes to the XmlDataSource while we are loading the document _disallowChanges = true; // Check if transform is specified. // If there is a transform, load the data, then the transform, and get an XmlReader from the transformation. transformReader = GetReader(TransformFile, Transform, out transformCacheDependency); if (transformReader != null) { // Now load the transform and pass it off to the reader #pragma warning disable 0618 // To avoid deprecation warning XslTransform transform = new XslTransform(); #pragma warning restore 0618 transform.Load(transformReader, null, null); OnTransforming(EventArgs.Empty); XmlDocument tempDocument = new XmlDocument(); tempDataReader = GetReader(DataFile, Data, out dataCacheDependency); tempDocument.Load(tempDataReader); // The XmlResolver cast on the third parameter is required to eliminate an ambiguity // from the compiler. dataReader = transform.Transform(tempDocument, _transformArgumentList, (XmlResolver)null); } else { dataReader = GetReader(DataFile, Data, out dataCacheDependency); } // Finally, load up the actual data document.Load(dataReader); } finally { _disallowChanges = false; if (dataReader != null) { dataReader.Close(); } if (tempDataReader != null) { tempDataReader.Close(); } if (transformReader != null) { transformReader.Close(); } } } ////// Called right before the XSLT transform is applied. /// This allows a developer to supply an XsltArgumentList in the TransformArgumentList property. /// protected virtual void OnTransforming(EventArgs e) { EventHandler handler = (EventHandler)Events[EventTransforming]; if (handler != null) { handler(this, e); } } ////// Saves the XML data to disk. /// public void Save() { if (!IsModifiable) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_SaveNotAllowed, ID)); } string writeableDataFile = WriteableDataFile; Debug.Assert(!String.IsNullOrEmpty(writeableDataFile), "Did not expect WriteableDataFile to be empty in Save()"); // Check for write permissions HttpRuntime.CheckFilePermission(writeableDataFile, true); // Save the document GetXmlDocument().Save(writeableDataFile); } #region Implementation of IDataSource event EventHandler IDataSource.DataSourceChanged { add { ((IHierarchicalDataSource)this).DataSourceChanged += value; } remove { ((IHierarchicalDataSource)this).DataSourceChanged -= value; } } ///DataSourceView IDataSource.GetView(string viewName) { if (viewName.Length == 0) { viewName = DefaultViewName; } return new XmlDataSourceView(this, viewName); } /// ICollection IDataSource.GetViewNames() { if (_viewNames == null) { _viewNames = new string[1] { DefaultViewName }; } return _viewNames; } #endregion #region Implementation of IListSource /// bool IListSource.ContainsListCollection { get { if (DesignMode) { return false; } return ListSourceHelper.ContainsListCollection(this); } } /// IList IListSource.GetList() { if (DesignMode) { return null; } return ListSourceHelper.GetList(this); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Web.UI.WebControls { using System; using System.Collections; using System.Collections.Specialized; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; using System.Globalization; using System.IO; using System.Security.Permissions; using System.Text; using System.Web; using System.Web.Hosting; using System.Web.Caching; using System.Web.UI; using System.Xml; using System.Xml.Xsl; using System.Web.Util; ////// Represents an XML file as both an IDataSource and an IHierarchicalDataSource. /// The XML data is retrieved either from a file specified by the DataFile property /// or by inline XML content in the Data property. /// [ DefaultEvent("Transforming"), DefaultProperty("DataFile"), Designer("System.Web.UI.Design.WebControls.XmlDataSourceDesigner, " + AssemblyRef.SystemDesign), ParseChildren(true), PersistChildren(false), ToolboxBitmap(typeof(XmlDataSource)), WebSysDescription(SR.XmlDataSource_Description), WebSysDisplayName(SR.XmlDataSource_DisplayName) ] [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)] [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)] public class XmlDataSource : HierarchicalDataSourceControl, IDataSource, IListSource { private static readonly object EventTransforming = new object(); private const string DefaultViewName = "DefaultView"; private DataSourceCache _cache; private bool _cacheLookupDone; private bool _disallowChanges; private XsltArgumentList _transformArgumentList; private ICollection _viewNames; private XmlDocument _xmlDocument; private string _writeableDataFile; private string _data; private string _dataFile; private string _transform; private string _transformFile; private string _xPath; ////// Specifies the cache settings for this data source. /// private DataSourceCache Cache { get { if (_cache == null) { _cache = new DataSourceCache(); _cache.Enabled = true; } return _cache; } } ////// The duration, in seconds, of the expiration. The expiration policy is specified by the CacheExpirationPolicy property. /// [ DefaultValue(DataSourceCache.Infinite), TypeConverterAttribute(typeof(DataSourceCacheDurationConverter)), WebCategory("Cache"), WebSysDescription(SR.DataSourceCache_Duration), ] public virtual int CacheDuration { get { return Cache.Duration; } set { Cache.Duration = value; } } ////// The expiration policy of the cache. The duration for the expiration is specified by the CacheDuration property. /// [ DefaultValue(DataSourceCacheExpiry.Absolute), WebCategory("Cache"), WebSysDescription(SR.DataSourceCache_ExpirationPolicy), ] public virtual DataSourceCacheExpiry CacheExpirationPolicy { get { return Cache.ExpirationPolicy; } set { Cache.ExpirationPolicy = value; } } ////// Indicates an arbitrary cache key to make this cache entry depend on. This allows /// the user to further customize when this cache entry will expire. /// [ DefaultValue(""), WebCategory("Cache"), WebSysDescription(SR.DataSourceCache_KeyDependency), ] public virtual string CacheKeyDependency { get { return Cache.KeyDependency; } set { Cache.KeyDependency = value; } } ////// Inline XML content. /// [ DefaultValue(""), Editor("System.ComponentModel.Design.MultilineStringEditor," + AssemblyRef.SystemDesign, typeof(UITypeEditor)), PersistenceMode(PersistenceMode.InnerProperty), TypeConverter("System.ComponentModel.MultilineStringConverter," + AssemblyRef.System), WebCategory("Data"), WebSysDescription(SR.XmlDataSource_Data), ] public virtual string Data { get { if (_data == null) { return String.Empty; } return _data; } set { if (value != null) { value = value.Trim(); } if (Data != value) { if (_disallowChanges) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_CannotChangeWhileLoading, "Data", ID)); } _data = value; _xmlDocument = null; OnDataSourceChanged(EventArgs.Empty); } } } ////// Path to an XML file. /// [ DefaultValue(""), Editor("System.Web.UI.Design.XmlDataFileEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)), WebCategory("Data"), WebSysDescription(SR.XmlDataSource_DataFile), ] public virtual string DataFile { get { if (_dataFile == null) { return String.Empty; } return _dataFile; } set { if (DataFile != value) { if (_disallowChanges) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_CannotChangeWhileLoading, "DataFile", ID)); } _dataFile = value; _xmlDocument = null; _writeableDataFile = null; OnDataSourceChanged(EventArgs.Empty); } } } ////// Whether caching is enabled for this data source. /// [ DefaultValue(true), WebCategory("Cache"), WebSysDescription(SR.DataSourceCache_Enabled), ] public virtual bool EnableCaching { get { return Cache.Enabled; } set { Cache.Enabled = value; } } ////// Indicates whether the XML data can be modified. /// This is also used by XmlDataSourceView to determine whether CanDelete/Insert/Update are true. /// internal bool IsModifiable { get { return (String.IsNullOrEmpty(TransformFile) && String.IsNullOrEmpty(Transform) && !String.IsNullOrEmpty(WriteableDataFile)); } } ////// Inline XSL transform. /// [ DefaultValue(""), Editor("System.ComponentModel.Design.MultilineStringEditor," + AssemblyRef.SystemDesign, typeof(UITypeEditor)), PersistenceMode(PersistenceMode.InnerProperty), TypeConverter("System.ComponentModel.MultilineStringConverter," + AssemblyRef.System), WebCategory("Data"), WebSysDescription(SR.XmlDataSource_Transform), ] public virtual string Transform { get { if (_transform == null) { return String.Empty; } return _transform; } set { if (value != null) { value = value.Trim(); } if (Transform != value) { if (_disallowChanges) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_CannotChangeWhileLoading, "Transform", ID)); } _transform = value; _xmlDocument = null; OnDataSourceChanged(EventArgs.Empty); } } } ////// Arguments for the XSL transform. /// This should be populated in the Transforming event. /// [ Browsable(false), ] public virtual XsltArgumentList TransformArgumentList { get { return _transformArgumentList; } set { _transformArgumentList = value; } } ////// Path to an XSL transform file. /// [ DefaultValue(""), Editor("System.Web.UI.Design.XslTransformFileEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)), WebCategory("Data"), WebSysDescription(SR.XmlDataSource_TransformFile), ] public virtual string TransformFile { get { if (_transformFile == null) { return String.Empty; } return _transformFile; } set { if (TransformFile != value) { if (_disallowChanges) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_CannotChangeWhileLoading, "TransformFile", ID)); } _transformFile = value; _xmlDocument = null; OnDataSourceChanged(EventArgs.Empty); } } } ////// Gets a physical path of the data file that can be written to. /// The value is null if the path is not a writable path. /// private string WriteableDataFile { get { if (_writeableDataFile == null) { _writeableDataFile = GetWriteableDataFile(); } return _writeableDataFile; } } ////// Specifies an initial XPath that is applied to the XML data. /// [ DefaultValue(""), WebCategory("Data"), WebSysDescription(SR.XmlDataSource_XPath), ] public virtual string XPath { get { if (_xPath == null) { return String.Empty; } return _xPath; } set { if (XPath != value) { if (_disallowChanges) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_CannotChangeWhileLoading, "XPath", ID)); } _xPath = value; OnDataSourceChanged(EventArgs.Empty); } } } ////// Raised before the XSL transform is applied. /// [ WebCategory("Data"), WebSysDescription(SR.XmlDataSource_Transforming), ] public event EventHandler Transforming { add { Events.AddHandler(EventTransforming, value); } remove { Events.RemoveHandler(EventTransforming, value); } } ////// Creates a unique cache key for this data source's data. /// private string CreateCacheKey() { StringBuilder sb = new StringBuilder(CacheInternal.PrefixDataSourceControl, 1024); sb.Append(GetType().GetHashCode().ToString(CultureInfo.InvariantCulture)); sb.Append(CacheDuration.ToString(CultureInfo.InvariantCulture)); sb.Append(':'); sb.Append(((int)CacheExpirationPolicy).ToString(CultureInfo.InvariantCulture)); bool includeUniqueID = false; if (DataFile.Length > 0) { sb.Append(':'); sb.Append(DataFile); } else { if (Data.Length > 0) { includeUniqueID = true; } } if (TransformFile.Length > 0) { sb.Append(':'); sb.Append(TransformFile); } else { if (Transform.Length > 0) { includeUniqueID = true; } } if (includeUniqueID) { // If we don't have any paths, use the Page if (Page != null) { sb.Append(':'); sb.Append(Page.GetType().AssemblyQualifiedName); } sb.Append(':'); string uniqueID = UniqueID; if (String.IsNullOrEmpty(uniqueID)) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_NeedUniqueIDForCache)); } sb.Append(uniqueID); } return sb.ToString(); } ////// Returns a HierarchicalDataSourceView based on an XPath specified by viewPath. /// protected override HierarchicalDataSourceView GetHierarchicalView(string viewPath) { return new XmlHierarchicalDataSourceView(this, viewPath); } ////// Gets an XmlReader representing XML or XSL content, and optionally a cache /// dependency for that content. /// Supported paths are: Relative paths, physical paths, UNC paths, and HTTP URLs /// If a path is not provided, the content parameter is assumed to contain the /// actual content. /// If there is no data, null is returned. /// This method is fully compatible with Virtual Path Providers. /// private XmlReader GetReader(string path, string content, out CacheDependency cacheDependency) { // If a filename is specified, load from file. Otherwise load from inner content. if (path.Length != 0) { // First try to detect if it is an HTTP URL Uri uri; bool success = Uri.TryCreate(path, UriKind.Absolute, out uri); if (success) { if (uri.Scheme == Uri.UriSchemeHttp) { // Check for Web permissions for the URL we want if (!HttpRuntime.HasWebPermission(uri)) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_NoWebPermission, uri.PathAndQuery, ID)); } // Dependencies are not supported with HTTP URLs cacheDependency = null; // If it is an HTTP URL and we have permissions, get a reader return new XmlTextReader(path); } } // Now see what kind of file-based path it is VirtualPath virtualPath; string physicalPath; ResolvePhysicalOrVirtualPath(path, out virtualPath, out physicalPath); if (virtualPath != null && DesignMode) { // This exception should never be thrown - the designer always maps paths // before using the runtime control. throw new NotSupportedException(SR.GetString(SR.XmlDataSource_DesignTimeRelativePathsNotSupported, ID)); } Stream dataStream = OpenFileAndGetDependency(virtualPath, physicalPath, out cacheDependency); return new XmlTextReader(dataStream); } else { // Dependencies are not supported with inline content cacheDependency = null; content = content.Trim(); if (content.Length == 0) { return null; } else { return new XmlTextReader(new StringReader(content)); } } } ////// Gets a path to a writeable file where we can save data to. /// The return value is null if a writeable path cannot be found. /// private string GetWriteableDataFile() { if (DataFile.Length != 0) { // First try to detect if it is an HTTP URL Uri uri; bool success = Uri.TryCreate(DataFile, UriKind.Absolute, out uri); if (success) { if (uri.Scheme == Uri.UriSchemeHttp) { // Cannot write to HTTP URLs return null; } } if (HostingEnvironment.UsingMapPathBasedVirtualPathProvider) { // Now see what kind of file-based path it is VirtualPath virtualPath; string physicalPath; ResolvePhysicalOrVirtualPath(DataFile, out virtualPath, out physicalPath); if (physicalPath == null) { physicalPath = virtualPath.MapPathInternal(this.TemplateControlVirtualDirectory, true /*allowCrossAppMapping*/); } return physicalPath; } else { // File is coming from a custom virtual path provider, and there is no support for writing return null; } } else { // Data is specified using Data property, so it is not writeable return null; } } ////// Returns the XmlDocument representing the XML data. /// If necessary, the XML data will be reloaded along with the transform, if available. /// public XmlDocument GetXmlDocument() { string cacheKey = null; if (!_cacheLookupDone && Cache.Enabled) { // If caching is enabled, attempt to load from cache. cacheKey = CreateCacheKey(); _xmlDocument = Cache.LoadDataFromCache(cacheKey) as XmlDocument; _cacheLookupDone = true; } if (_xmlDocument == null) { // Load up the data _xmlDocument = new XmlDocument(); CacheDependency transformCacheDependency; CacheDependency dataCacheDependency; PopulateXmlDocument(_xmlDocument, out dataCacheDependency, out transformCacheDependency); if (cacheKey != null) { Debug.Assert(Cache.Enabled); // If caching is enabled, save the XmlDocument to cache. CacheDependency fileDependency; if (dataCacheDependency != null) { if (transformCacheDependency != null) { // We have both a data file as well as a transform file dependency AggregateCacheDependency aggregateDependency = new AggregateCacheDependency(); aggregateDependency.Add(dataCacheDependency, transformCacheDependency); fileDependency = aggregateDependency; } else { // We only have a data file dependency fileDependency = dataCacheDependency; } } else { // We have at most only a transform file dependency (or no dependency at all) fileDependency = transformCacheDependency; } Cache.SaveDataToCache(cacheKey, _xmlDocument, fileDependency); } } return _xmlDocument; } ////// Populates an XmlDocument with the appropriate XML data, including applying transforms. /// private void PopulateXmlDocument(XmlDocument document, out CacheDependency dataCacheDependency, out CacheDependency transformCacheDependency) { XmlReader transformReader = null; XmlReader dataReader = null; XmlReader tempDataReader = null; try { // Don't allow changes to the XmlDataSource while we are loading the document _disallowChanges = true; // Check if transform is specified. // If there is a transform, load the data, then the transform, and get an XmlReader from the transformation. transformReader = GetReader(TransformFile, Transform, out transformCacheDependency); if (transformReader != null) { // Now load the transform and pass it off to the reader #pragma warning disable 0618 // To avoid deprecation warning XslTransform transform = new XslTransform(); #pragma warning restore 0618 transform.Load(transformReader, null, null); OnTransforming(EventArgs.Empty); XmlDocument tempDocument = new XmlDocument(); tempDataReader = GetReader(DataFile, Data, out dataCacheDependency); tempDocument.Load(tempDataReader); // The XmlResolver cast on the third parameter is required to eliminate an ambiguity // from the compiler. dataReader = transform.Transform(tempDocument, _transformArgumentList, (XmlResolver)null); } else { dataReader = GetReader(DataFile, Data, out dataCacheDependency); } // Finally, load up the actual data document.Load(dataReader); } finally { _disallowChanges = false; if (dataReader != null) { dataReader.Close(); } if (tempDataReader != null) { tempDataReader.Close(); } if (transformReader != null) { transformReader.Close(); } } } ////// Called right before the XSLT transform is applied. /// This allows a developer to supply an XsltArgumentList in the TransformArgumentList property. /// protected virtual void OnTransforming(EventArgs e) { EventHandler handler = (EventHandler)Events[EventTransforming]; if (handler != null) { handler(this, e); } } ////// Saves the XML data to disk. /// public void Save() { if (!IsModifiable) { throw new InvalidOperationException(SR.GetString(SR.XmlDataSource_SaveNotAllowed, ID)); } string writeableDataFile = WriteableDataFile; Debug.Assert(!String.IsNullOrEmpty(writeableDataFile), "Did not expect WriteableDataFile to be empty in Save()"); // Check for write permissions HttpRuntime.CheckFilePermission(writeableDataFile, true); // Save the document GetXmlDocument().Save(writeableDataFile); } #region Implementation of IDataSource event EventHandler IDataSource.DataSourceChanged { add { ((IHierarchicalDataSource)this).DataSourceChanged += value; } remove { ((IHierarchicalDataSource)this).DataSourceChanged -= value; } } ///DataSourceView IDataSource.GetView(string viewName) { if (viewName.Length == 0) { viewName = DefaultViewName; } return new XmlDataSourceView(this, viewName); } /// ICollection IDataSource.GetViewNames() { if (_viewNames == null) { _viewNames = new string[1] { DefaultViewName }; } return _viewNames; } #endregion #region Implementation of IListSource /// bool IListSource.ContainsListCollection { get { if (DesignMode) { return false; } return ListSourceHelper.ContainsListCollection(this); } } /// IList IListSource.GetList() { if (DesignMode) { return null; } return ListSourceHelper.GetList(this); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- RegexStringValidator.cs
- DSACryptoServiceProvider.cs
- AnchorEditor.cs
- GridViewPageEventArgs.cs
- TextParagraph.cs
- ImageAutomationPeer.cs
- MD5CryptoServiceProvider.cs
- Int32Rect.cs
- PathGeometry.cs
- TargetConverter.cs
- MultipartIdentifier.cs
- PeerChannelFactory.cs
- TreeNodeMouseHoverEvent.cs
- ToolStripSystemRenderer.cs
- AuthenticationModulesSection.cs
- ButtonColumn.cs
- MemoryFailPoint.cs
- RtfControls.cs
- TrustManagerPromptUI.cs
- DispatcherObject.cs
- SchemaComplexType.cs
- PanelDesigner.cs
- HttpModuleCollection.cs
- BlurBitmapEffect.cs
- DateTimeStorage.cs
- ListParagraph.cs
- IriParsingElement.cs
- ViewPort3D.cs
- TargetFrameworkAttribute.cs
- UnmanagedMemoryStream.cs
- SectionUpdates.cs
- GlyphRunDrawing.cs
- CannotUnloadAppDomainException.cs
- ZipIOCentralDirectoryBlock.cs
- QilGeneratorEnv.cs
- FontNamesConverter.cs
- SmtpNtlmAuthenticationModule.cs
- Win32SafeHandles.cs
- ExtensionWindowResizeGrip.cs
- AmbientLight.cs
- AnnotationService.cs
- COM2IDispatchConverter.cs
- Random.cs
- CompilationUtil.cs
- NameObjectCollectionBase.cs
- ProfileModule.cs
- TimeStampChecker.cs
- ISFTagAndGuidCache.cs
- SqlUtil.cs
- RequestQueue.cs
- TemplateColumn.cs
- SimpleBitVector32.cs
- ZoneButton.cs
- XPathNodeInfoAtom.cs
- ToolboxDataAttribute.cs
- FastPropertyAccessor.cs
- Debug.cs
- DataGridViewImageColumn.cs
- SocketPermission.cs
- HtmlElement.cs
- SingleKeyFrameCollection.cs
- HttpResponseInternalWrapper.cs
- Deserializer.cs
- x509utils.cs
- ReadOnlyHierarchicalDataSource.cs
- InboundActivityHelper.cs
- RegularExpressionValidator.cs
- UrlMappingCollection.cs
- PageParser.cs
- SqlUtil.cs
- FileLogRecordStream.cs
- DataGridViewCellFormattingEventArgs.cs
- InvokeHandlers.cs
- StorageRoot.cs
- DiagnosticTrace.cs
- _SslState.cs
- FigureHelper.cs
- CdpEqualityComparer.cs
- SqlInfoMessageEvent.cs
- DataGridTableCollection.cs
- InfoCardSymmetricAlgorithm.cs
- sqlstateclientmanager.cs
- LinqDataSourceInsertEventArgs.cs
- Preprocessor.cs
- TypographyProperties.cs
- LocalizationComments.cs
- OleDbConnectionFactory.cs
- OleDbErrorCollection.cs
- SecurityTokenAttachmentMode.cs
- BindingList.cs
- ExpressionNormalizer.cs
- WebConfigurationFileMap.cs
- DeflateStream.cs
- WebFormDesignerActionService.cs
- XPathNodeList.cs
- StylusCollection.cs
- BasicExpandProvider.cs
- ColumnBinding.cs
- DivideByZeroException.cs
- ComponentEditorPage.cs