Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / 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.
//
//-----------------------------------------------------------------------------
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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- URLString.cs
- RemotingSurrogateSelector.cs
- ObjectDisposedException.cs
- ChannelSinkStacks.cs
- WebPartTransformer.cs
- XmlAttributeHolder.cs
- SqlCommandBuilder.cs
- ExtenderProvidedPropertyAttribute.cs
- SystemColorTracker.cs
- ColorTranslator.cs
- PolicyStatement.cs
- TdsParserSessionPool.cs
- QilUnary.cs
- AutomationProperties.cs
- ValueHandle.cs
- SrgsToken.cs
- StateMachineDesignerPaint.cs
- UniqueCodeIdentifierScope.cs
- Certificate.cs
- ListViewItem.cs
- GcSettings.cs
- WithStatement.cs
- RepeatBehavior.cs
- InputScopeNameConverter.cs
- RoutedCommand.cs
- ReachFixedPageSerializerAsync.cs
- RegexMatch.cs
- NetworkStream.cs
- StylusPointCollection.cs
- messageonlyhwndwrapper.cs
- NullReferenceException.cs
- XmlNodeComparer.cs
- InputLanguageManager.cs
- AssemblyUtil.cs
- SQLByte.cs
- RenderingEventArgs.cs
- LexicalChunk.cs
- XmlSchemaAttributeGroupRef.cs
- FileUtil.cs
- EntityTypeBase.cs
- UnitControl.cs
- ClipboardData.cs
- TemplateControlBuildProvider.cs
- InvalidProgramException.cs
- PackageRelationshipSelector.cs
- COSERVERINFO.cs
- Matrix3DValueSerializer.cs
- TextRangeEdit.cs
- PrivilegeNotHeldException.cs
- ComboBoxRenderer.cs
- Metadata.cs
- HorizontalAlignConverter.cs
- ImageIndexConverter.cs
- DropDownList.cs
- MetadataArtifactLoader.cs
- DelegatingConfigHost.cs
- BaseValidator.cs
- AlternateView.cs
- RegexGroup.cs
- PropertiesTab.cs
- SqlExpander.cs
- BuilderPropertyEntry.cs
- RuleSetBrowserDialog.cs
- Int64.cs
- MarkupExtensionParser.cs
- ReceiveSecurityHeader.cs
- DataServiceQueryOfT.cs
- PersonalizationProviderHelper.cs
- Sql8ExpressionRewriter.cs
- TypefaceCollection.cs
- IsolationInterop.cs
- PriorityBinding.cs
- SpecularMaterial.cs
- clipboard.cs
- DecimalStorage.cs
- AllMembershipCondition.cs
- NavigatingCancelEventArgs.cs
- KeyNotFoundException.cs
- CurrentChangingEventArgs.cs
- DataGridViewCellErrorTextNeededEventArgs.cs
- Compiler.cs
- HttpRequestTraceRecord.cs
- DataServiceContext.cs
- D3DImage.cs
- ReadOnlyHierarchicalDataSourceView.cs
- EdmItemCollection.cs
- PostBackOptions.cs
- FileDataSourceCache.cs
- SimpleRecyclingCache.cs
- SqlDataSource.cs
- CodeNamespaceImportCollection.cs
- CellIdBoolean.cs
- TypeHelper.cs
- ConfigurationStrings.cs
- X509WindowsSecurityToken.cs
- Span.cs
- NavigationEventArgs.cs
- FieldTemplateUserControl.cs
- WindowsStatic.cs
- FormParameter.cs