Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / 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(':');
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
- BlobPersonalizationState.cs
- ProviderConnectionPoint.cs
- Inflater.cs
- AssertValidation.cs
- DetailsViewPagerRow.cs
- SizeChangedInfo.cs
- KeyedHashAlgorithm.cs
- RepeatButton.cs
- UnsafeNativeMethods.cs
- MethodCallTranslator.cs
- Action.cs
- HttpCapabilitiesEvaluator.cs
- ModelVisual3D.cs
- ExpressionList.cs
- RepeaterCommandEventArgs.cs
- altserialization.cs
- LicenseContext.cs
- MsmqInputChannelListener.cs
- X509UI.cs
- StickyNoteContentControl.cs
- SerializerDescriptor.cs
- IntegerValidatorAttribute.cs
- mactripleDES.cs
- HttpModuleActionCollection.cs
- ValuePattern.cs
- X509SubjectKeyIdentifierClause.cs
- XmlUtil.cs
- SqlRemoveConstantOrderBy.cs
- ContainerParagraph.cs
- MetadataItem_Static.cs
- SettingsBase.cs
- ObjectViewEntityCollectionData.cs
- LogWriteRestartAreaAsyncResult.cs
- DebugHandleTracker.cs
- EmbeddedObject.cs
- TextRangeEdit.cs
- Events.cs
- EncodingDataItem.cs
- PreviewPrintController.cs
- SqlBuffer.cs
- Track.cs
- CodeCompileUnit.cs
- DataGridRelationshipRow.cs
- CngKey.cs
- RelationshipConverter.cs
- RowUpdatedEventArgs.cs
- ProcessModelInfo.cs
- BuildProvidersCompiler.cs
- RefreshPropertiesAttribute.cs
- HttpGetProtocolReflector.cs
- StringCollection.cs
- PropertyGridCommands.cs
- XmlSerializerFactory.cs
- CursorConverter.cs
- InfoCardRSAPKCS1SignatureFormatter.cs
- UriSection.cs
- SizeFConverter.cs
- SoapIncludeAttribute.cs
- XsdBuildProvider.cs
- ReflectTypeDescriptionProvider.cs
- Enumerable.cs
- ResourceSetExpression.cs
- Size.cs
- ThreadPool.cs
- XmlElementList.cs
- WarningException.cs
- ThreadStateException.cs
- DoubleUtil.cs
- ListViewGroupCollectionEditor.cs
- wmiprovider.cs
- HostAdapter.cs
- Operand.cs
- rsa.cs
- CorrelationToken.cs
- CompositeDataBoundControl.cs
- XmlSerializerVersionAttribute.cs
- ScaleTransform.cs
- QueryOutputWriter.cs
- FakeModelItemImpl.cs
- PerformanceCounterPermissionEntry.cs
- StringStorage.cs
- ItemsControlAutomationPeer.cs
- MappingSource.cs
- DatePickerTextBox.cs
- ItemList.cs
- GacUtil.cs
- MemberCollection.cs
- PublisherIdentityPermission.cs
- Frame.cs
- TreeBuilder.cs
- DataGridCell.cs
- NumericPagerField.cs
- MonikerBuilder.cs
- AmbientLight.cs
- StructuredType.cs
- DataViewSettingCollection.cs
- BulletedListEventArgs.cs
- Group.cs
- NativeMethods.cs
- UserControlParser.cs