Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / xsp / System / Web / UI / WebControls / XmlDataSource.cs / 1 / 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(':'); 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 } }
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ItemChangedEventArgs.cs
- Operand.cs
- FastEncoder.cs
- NumericUpDownAccelerationCollection.cs
- RequestStatusBarUpdateEventArgs.cs
- UserPrincipalNameElement.cs
- MimePart.cs
- ComponentCollection.cs
- WebScriptMetadataFormatter.cs
- DiscoveryEndpoint.cs
- WindowsRichEdit.cs
- ACE.cs
- GenericAuthenticationEventArgs.cs
- XmlSchemaAttributeGroup.cs
- HwndSource.cs
- COM2ColorConverter.cs
- ExternalCalls.cs
- OracleParameterCollection.cs
- DataGridViewCellParsingEventArgs.cs
- PtsPage.cs
- XslAstAnalyzer.cs
- XmlArrayItemAttributes.cs
- TransactionsSectionGroup.cs
- FixedSOMPageElement.cs
- DragDeltaEventArgs.cs
- XmlSchemaComplexType.cs
- ArgIterator.cs
- DataRelationPropertyDescriptor.cs
- CodeDomLoader.cs
- MultiBinding.cs
- DetailsViewCommandEventArgs.cs
- ListItem.cs
- RowToFieldTransformer.cs
- WebPartManagerInternals.cs
- SerializationEventsCache.cs
- ConfigurationPropertyCollection.cs
- ValueType.cs
- HexParser.cs
- WebBrowsableAttribute.cs
- PropertyValueChangedEvent.cs
- MessageQueueTransaction.cs
- TextRangeAdaptor.cs
- GroupAggregateExpr.cs
- ChangesetResponse.cs
- CodeAttributeArgument.cs
- SmiGettersStream.cs
- SqlMethodTransformer.cs
- RelatedCurrencyManager.cs
- BuildManagerHost.cs
- _TimerThread.cs
- BrowserCapabilitiesCompiler.cs
- SQLSingle.cs
- ProcessModuleCollection.cs
- WebPartCloseVerb.cs
- MaxMessageSizeStream.cs
- PersistenceTypeAttribute.cs
- TemplateBamlTreeBuilder.cs
- TextRangeProviderWrapper.cs
- DataGridViewRow.cs
- HtmlPanelAdapter.cs
- WindowsTab.cs
- RequestFactory.cs
- ControlBindingsCollection.cs
- Error.cs
- Process.cs
- CollectionDataContractAttribute.cs
- DataGridItem.cs
- WebPartMovingEventArgs.cs
- PointValueSerializer.cs
- AttachedPropertyMethodSelector.cs
- COM2Enum.cs
- ProtocolsSection.cs
- PingOptions.cs
- RangeValidator.cs
- SettingsProviderCollection.cs
- IFormattable.cs
- DataKey.cs
- WindowsListViewScroll.cs
- QueryAccessibilityHelpEvent.cs
- SqlDataSourceQuery.cs
- GridView.cs
- OracleInternalConnection.cs
- ConfigXmlElement.cs
- ADMembershipProvider.cs
- MetadataPropertyAttribute.cs
- GlyphsSerializer.cs
- OSFeature.cs
- SmtpMail.cs
- GacUtil.cs
- CodeDefaultValueExpression.cs
- SeverityFilter.cs
- MouseActionValueSerializer.cs
- SynchronousSendBindingElement.cs
- RestHandler.cs
- StatusBarPanelClickEvent.cs
- List.cs
- Classification.cs
- BufferedWebEventProvider.cs
- DefaultObjectMappingItemCollection.cs
- AssemblyAttributesGoHere.cs