Files
acceptance-tests
data
debian
docs
external
ikvm-native
llvm
m4
man
mcs
build
class
Accessibility
Commons.Xml.Relaxng
Cscompmgd
CustomMarshalers
Facades
I18N
IBM.Data.DB2
ICSharpCode.SharpZipLib
Microsoft.Build
Microsoft.Build.Engine
Microsoft.Build.Framework
Microsoft.Build.Tasks
Microsoft.Build.Utilities
Microsoft.CSharp
Microsoft.NuGet.Build.Tasks
Microsoft.VisualC
Microsoft.Web.Infrastructure
MicrosoftAjaxLibrary
Mono.Btls.Interface
Mono.C5
Mono.CSharp
Mono.Cairo
Mono.Cecil
Mono.Cecil.Mdb
Mono.CodeContracts
Mono.CompilerServices.SymbolWriter
Mono.Data.Sqlite
Mono.Data.Tds
Mono.Debugger.Soft
Mono.Http
Mono.Management
Mono.Messaging
Mono.Messaging.RabbitMQ
Mono.Options
Mono.Parallel
Mono.Posix
Mono.Profiler.Log
Mono.Runtime.Tests
Mono.Security
Mono.Security.Win32
Mono.Simd
Mono.Tasklets
Mono.WebBrowser
Mono.XBuild.Tasks
Novell.Directory.Ldap
PEAPI
RabbitMQ.Client
SMDiagnostics
System
System.ComponentModel.Composition.4.5
System.ComponentModel.DataAnnotations
System.Configuration
System.Configuration.Install
System.Core
System.Data
System.Data.DataSetExtensions
System.Data.Entity
System.Data.Linq
System.Data.OracleClient
System.Data.Services
System.Data.Services.Client
System.Deployment
System.Design
System.DirectoryServices
System.DirectoryServices.Protocols
System.Drawing
System.Drawing.Design
System.Dynamic
System.EnterpriseServices
System.IO.Compression
System.IO.Compression.FileSystem
System.IdentityModel
System.IdentityModel.Selectors
System.Json
System.Json.Microsoft
System.Management
System.Messaging
System.Net
System.Net.Http
System.Net.Http.Formatting
System.Net.Http.WebRequest
System.Net.Http.WinHttpHandler
System.Numerics
System.Numerics.Vectors
System.Reactive.Core
System.Reactive.Debugger
System.Reactive.Experimental
System.Reactive.Interfaces
System.Reactive.Linq
System.Reactive.Observable.Aliases
System.Reactive.PlatformServices
System.Reactive.Providers
System.Reactive.Runtime.Remoting
System.Reactive.Windows.Forms
System.Reactive.Windows.Threading
System.Reflection.Context
System.Runtime.Caching
System.Runtime.CompilerServices.Unsafe
System.Runtime.DurableInstancing
System.Runtime.Remoting
System.Runtime.Serialization
System.Runtime.Serialization.Formatters.Soap
System.Security
System.ServiceModel
System.ServiceModel.Activation
System.ServiceModel.Discovery
System.ServiceModel.Internals
System.ServiceModel.Routing
System.ServiceModel.Web
System.ServiceProcess
System.Threading.Tasks.Dataflow
System.Transactions
System.Web
System.Web.Abstractions
System.Web.ApplicationServices
System.Web.DynamicData
System.Web.Extensions
System.Web.Extensions.Design
System.Web.Http
System.Web.Http.SelfHost
System.Web.Http.WebHost
System.Web.Mobile
System.Web.Mvc3
System.Web.Razor
System.Web.RegularExpressions
System.Web.Routing
System.Web.Services
System.Web.WebPages
System.Web.WebPages.Deployment
System.Web.WebPages.Razor
System.Windows
System.Windows.Forms
System.Windows.Forms.DataVisualization
System.Workflow.Activities
System.Workflow.ComponentModel
System.Workflow.Runtime
System.XML
System.Xaml
System.Xml.Linq
System.Xml.Serialization
SystemWebTestShim
WebMatrix.Data
WindowsBase
aot-compiler
corlib
dlr
doc
legacy
lib
monodoc
notes
reference-assemblies
referencesource
SMDiagnostics
System
System.Activities
System.Activities.Core.Presentation
System.Activities.DurableInstancing
System.Activities.Presentation
System.ComponentModel.DataAnnotations
System.Configuration
System.Core
System.Data
System.Data.DataSetExtensions
System.Data.Entity
System.Data.Entity.Design
System.Data.Linq
System.Data.SqlXml
System.IdentityModel
System.IdentityModel.Selectors
System.Net
System.Numerics
System.Runtime.Caching
System.Runtime.DurableInstancing
System.Runtime.Serialization
System.ServiceModel
System.ServiceModel.Activation
System.ServiceModel.Activities
System.ServiceModel.Channels
System.ServiceModel.Discovery
System.ServiceModel.Internals
System.ServiceModel.Routing
System.ServiceModel.WasHosting
System.ServiceModel.Web
System.Web
Abstractions
Administration
Cache
Compilation
Configuration
DataAccess
DataAnnotations
Handlers
Hosting
Instrumentation
InternalApis
IntraPartitionAPIs
Management
ModelBinding
Profile
Properties
Routing
Security
State
UI
HtmlControls
WebControls
WebParts
ApplicationFileParser.cs
AttributeCollection.cs
BaseParser.cs
BaseTemplateParser.cs
BatchParser.cs
BindableTemplateBuilder.cs
BoundPropertyEntry.cs
BuilderPropertyEntry.cs
ChtmlTextWriter.cs
ClientIDMode.cs
ClientScriptManager.cs
CodeBlockBuilder.cs
CodeStatementBuilder.cs
CollectionBuilder.cs
ComplexPropertyEntry.cs
ConflictOptions.cs
ConstructorNeedsTagAttribute.cs
Control.cs.REMOVED.git-id
ControlAdapter.cs
ControlBuilder.cs.REMOVED.git-id
ControlBuilderAttribute.cs
ControlCachePolicy.cs
ControlCollection.cs
ControlIdConverter.cs
ControlPropertyNameConverter.cs
ControlRenderingHelper.cs
ControlState.cs
ControlValuePropertyAttribute.cs
CssClassPropertyAttribute.cs
CssStyleCollection.cs
CssTextWriter.cs
DataBinder.cs
DataBinding.cs
DataBindingCollection.cs
DataBindingHandlerAttribute.cs
DataBoundLiteralControl.cs
DataKeyPropertyAttribute.cs
DataSourceCache.cs
DataSourceCacheDurationConverter.cs
DataSourceCacheExpiry.cs
DataSourceCapabilities.cs
DataSourceControl.cs
DataSourceControlBuilder.cs
DataSourceHelper.cs
DataSourceOperation.cs
DataSourceSelectArguments.cs
DataSourceView.cs
DataSourceViewOperationDelegates.cs
DesignTimeParseData.cs
DesignTimeTemplateParser.cs
EmptyControlCollection.cs
EmptyTextWriter.cs
ErrorFormatterPage.cs
EventEntry.cs
EventValidationStore.cs
ExpressionBinding.cs
ExpressionBindingCollection.cs
FileDataSourceCache.cs
FileLevelControlBuilderAttribute.cs
FilterableAttribute.cs
FilteredAttributeCollection.cs
HTMLTagNameToTypeMapper.cs
HTMLTextWriter.cs
HiddenFieldPageStatePersister.cs
HierarchicalDataSourceControl.cs
HierarchicalDataSourceView.cs
Html32TextWriter.cs
HtmlControlPersistable.cs
HtmlForm.cs
HtmlTextWriterAttribute.cs
HtmlTextWriterStyle.cs
HtmlTextWriterTag.cs
IAttributeAccessor.cs
IAutoFieldGenerator.cs
IBindableControl.cs
IBindableTemplate.cs
ICallbackEventHandler.cs
ICodeBlockTypeAccessor.cs
IControlBuilderAccessor.cs
IControlDesignerAccessor.cs
IDReferencePropertyAttribute.cs
IDataBindingsAccessor.cs
IDataItemContainer.cs
IDataKeysControl.cs
IDataSource.cs
IDataSourceViewSchemaAccessor.cs
IExpressionsAccessor.cs
IFilterResolutionService.cs
IHierarchicalDataSource.cs
IHierarchicalEnumerable.cs
IHierarchyData.cs
INamingContainer.cs
INavigateUIData.cs
INonBindingContainer.cs
IPageAsyncTask.cs
IParserAccessor.cs
IPostBackDataHandler.cs
IPostBackEventHandler.cs
IResourceUrlGenerator.cs
IScriptManager.cs
IScriptResourceDefinition.cs
IScriptResourceMapping.cs
IStateFormatter.cs
IStateFormatter2.cs
IStateManager.cs
IStyleSheet.cs
ITemplate.cs
IThemeResolutionService.cs
IUpdatePanel.cs
IUrlResolutionService.cs
IUserControlDesignerAccessor.cs
IUserControlTypeResolutionService.cs
IValidator.cs
ImageClickEventArgs.cs
ImageClickEventHandler.cs
IndexedString.cs
InternalControlCollection.cs
LOSFormatter.cs
LegacyPageAsyncTask.cs
LegacyPageAsyncTaskManager.cs
ListSourceHelper.cs
LiteralControl.cs
LosWriter.cs
MasterPage.cs
MasterPageParser.cs
MinimizableAttributeTypeConverter.cs
NonVisualControlAttribute.cs
ObjectConverter.cs
ObjectPersistData.cs
ObjectStateFormatter.cs
ObjectTag.cs
OrderedDictionaryStateHelper.cs
OutputCacheSettings.cs
Page.cs.REMOVED.git-id
PageAdapter.cs
PageAsyncTask.cs
PageAsyncTaskApm.cs
PageAsyncTaskManager.cs
PageAsyncTaskTap.cs
PageHandlerFactory.cs
PageParser.cs
PageParserFilter.cs
PageStatePersister.cs
PageTheme.cs
PageThemeParser.cs
PagesConfiguration.cs
Pair.cs
ParseChildrenAsPropertiesAttribute.cs
ParseRecorder.cs
ParsedAttributeCollection.cs
PartialCachingAttribute.cs
PartialCachingControl.cs
PersistChildrenAttribute.cs
PersistenceMode.cs
PersistenceTypeAttribute.cs
PostBackOptions.cs
PropertyConverter.cs
PropertyEntry.cs
PropertyMapper.cs
RenderTraceListener.cs
RootBuilder.cs
SessionPageStatePersister.cs
SimpleHandlerFactory.cs
SimplePropertyEntry.cs
SimpleWebHandlerParser.cs
SkinBuilder.cs
SqlDataSourceCache.cs
StateBag.cs
StateItem.cs
StateManagedCollection.cs
StringPropertyBuilder.cs
SupportsEventValidationAttribute.cs
TagNameToTypeMapper.cs
TagPrefixAttribute.cs
TargetFrameworkUtil.cs
TemplateBuilder.cs
TemplateControl.cs
TemplateControlParser.cs
TemplateInstance.cs
TemplateInstanceAttribute.cs
TemplateParser.cs.REMOVED.git-id
TemplatePropertyEntry.cs
ThemeableAttribute.cs
ToolboxDataAttribute.cs
TraceContext.cs
TraceContextEventArgs.cs
TraceContextEventHandler.cs
TraceContextRecord.cs
TraceModeEnum.cs
Triplet.cs
UnobtrusiveValidationMode.cs
UrlPropertyAttribute.cs
UserControl.cs
UserControlParser.cs
Util.cs
ValidateRequestMode.cs
ValidationPropertyAttribute.cs
ValidationSettings.cs
ValidatorCollection.cs
VerificationAttribute.cs
ViewStateEncryptionMode.cs
ViewStateException.cs
ViewStateMode.cs
ViewStateModeByIdAttribute.cs
WebResourceAttribute.cs
WmlTextWriter.cs
XPathBinder.cs
XhtmlTextWriter.cs
controlskin.cs
Util
WebSockets
misc
AspNetEventSource.cs
AspNetSynchronizationContext.cs
AspNetSynchronizationContextBase.cs
BufferAllocator.cs
CachedPathData.cs
CrossSiteScriptingValidation.cs
DefaultHttpHandler.cs
DynamicModuleRegistry.cs
DynamicValidationShim.cs
ErrorFormatter.cs
EtwTrace.cs
EventHandlerTaskAsyncHelper.cs
FileChangesMonitor.cs.REMOVED.git-id
GlobalSuppressions.cs.REMOVED.git-id
GlobalSuppressions2.cs.REMOVED.git-id
GlobalSuppressions3.cs
GlobalSuppressions4.cs
HTTPNotFoundHandler.cs
HtmlString.cs
HttpApplication.cs.REMOVED.git-id
HttpApplicationFactory.cs
HttpAsyncResult.cs
HttpBrowserCapabilities.cs
HttpBufferlessInputStream.cs
HttpCacheParams.cs
HttpCachePolicy.cs
HttpCacheVary.cs
HttpCacheVaryByContentEncodings.cs
HttpChannelBindingToken.cs
HttpClientCertificate.cs
HttpContext.cs
HttpCookie.cs
HttpCookieCollection.cs
HttpDebugHandler.cs
HttpDictionary.cs
HttpException.cs
HttpFileCollection.cs
HttpHeaderCollection.cs
HttpInputStream.cs
HttpModuleCollection.cs
HttpPostedFile.cs
HttpRawResponse.cs
HttpRequest.cs.REMOVED.git-id
HttpResponse.cs.REMOVED.git-id
HttpResponseHeader.cs
HttpRuntime.cs.REMOVED.git-id
HttpServerVarsCollection.cs
HttpTaskAsyncHandler.cs
HttpValueCollection.cs
HttpWriter.cs
IHtmlString.cs
IHttpAsyncHandler.cs
IHttpHandler.cs
IHttpHandlerFactory.cs
IHttpModule.cs
IPrincipalContainer.cs
IRequestCompletedNotifier.cs
ISubscriptionToken.cs
ITlsTokenBindingInfo.cs
IdleTimeoutMonitor.cs
IisTraceListener.cs
ImpersonationContext.cs
ImplicitAsyncPreloadModule.cs
IntSecurity.cs
LegacyAspNetSynchronizationContext.cs
MimeMapping.cs
ModuleConfigurationInfo.cs
ModulesEntry.cs
MultipartContentParser.cs
NativeMethods.cs
NotificationContext.cs
OutputCacheModule.cs
PartitionResolver.cs
PerfCounters.cs
PipelineModuleStepContainer.cs
PreApplicationStartMethodAttribute.cs
ProcessInfo.cs
ProcessModelInfo.cs
ReadEntityBodyMode.cs
RequestNotification.cs
RequestNotificationStatus.cs
RequestQueue.cs
RequestTimeoutManager.cs
RootedObjects.cs
SafeNativeMethods.cs
SiteMap.cs
SiteMapNode.cs
SiteMapNodeCollection.cs
SiteMapProvider.cs
StaticFileHandler.cs
StaticSiteMapProvider.cs
StringResourceManager.cs
System.Web.txt.REMOVED.git-id
TaskAsyncHelper.cs
TaskWrapperAsyncResult.cs
ThreadContext.cs
UnsafeNativeMethods.cs
UnvalidatedRequestValues.cs
UnvalidatedRequestValuesBase.cs
UnvalidatedRequestValuesWrapper.cs
UrlMappingsModule.cs
ValidateStringCallback.cs
VirtualPath.cs
VirtualPathUtility.cs
WebCategoryAttribute.cs
WebPageTraceListener.cs
WebSocketPipeline.cs
WebSocketTransitionState.cs
WebSysDefaultValueAttribute.cs
WebSysDescriptionAttribute.cs
WebSysDisplayNameAttribute.cs
WorkerRequest.cs
XmlSiteMapProvider.cs
cacheexpires.cspp
cacheusage.cspp
httpapplicationstate.cs
httpserverutility.cs
httpstaticobjectscollection.cs
System.Web.ApplicationServices
System.Web.DataVisualization
System.Web.DynamicData
System.Web.Entity
System.Web.Entity.Design
System.Web.Extensions
System.Web.Mobile
System.Web.Routing
System.Web.Services
System.Workflow.Activities
System.Workflow.ComponentModel
System.Workflow.Runtime
System.WorkflowServices
System.Xaml.Hosting
System.Xml
System.Xml.Linq
XamlBuildTask
mscorlib
LICENSE.txt
PATENTS.TXT
README.Mono.md
README.md
test-helpers
LICENSE
Makefile
Open.snk
README
ecma.pub
mono.pub
mono.snk
msfinal.pub
reactive.pub
silverlight.pub
winfx.pub
winfx3.pub
docs
errors
ilasm
jay
mcs
packages
tests
tools
AUTHORS
COPYING
INSTALL.txt
Makefile
MonoIcon.png
README
ScalableMonoIcon.svg
mkinstalldirs
mk
mono
msvc
netcore
po
runtime
samples
scripts
support
tools
COPYING.LIB
LICENSE
Makefile.am
Makefile.in
NEWS
README.md
acinclude.m4
aclocal.m4
autogen.sh
code_of_conduct.md
compile
config.guess
config.h.in
config.rpath
config.sub
configure.REMOVED.git-id
configure.ac.REMOVED.git-id
depcomp
install-sh
ltmain.sh.REMOVED.git-id
missing
mkinstalldirs
mono-uninstalled.pc.in
test-driver
winconfig.h
linux-packaging-mono/mcs/class/referencesource/System.Web/UI/PartialCachingControl.cs

858 lines
31 KiB
C#
Raw Normal View History

//------------------------------------------------------------------------------
// <copyright file="PartialCachingControl.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Web.UI {
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Globalization;
using System.Web;
using System.Web.Util;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.Caching;
using System.Web.Compilation;
using System.Web.Configuration;
using System.Security.Permissions;
// Keeps track of one call to Page Register* API
// The semantics of the fields depends to the call type
[Serializable]
internal class RegisterCallData {
internal ClientAPIRegisterType Type;
internal ScriptKey Key;
internal string StringParam1;
internal string StringParam2;
internal string StringParam3;
}
// Data that we need to cache
[Serializable]
internal class PartialCachingCacheEntry {
internal Guid _cachedVaryId;
internal string _dependenciesKey;
internal string[] _dependencies; // file dependencies
internal string OutputString;
internal string CssStyleString;
internal ArrayList RegisteredClientCalls;
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
[
ToolboxItem(false)
]
public abstract class BasePartialCachingControl : Control {
internal Control _cachedCtrl;
private long _nonVaryHashCode;
internal string _ctrlID;
internal string _guid;
internal DateTime _utcExpirationTime;
internal bool _useSlidingExpiration;
internal HttpCacheVaryByParams _varyByParamsCollection;
internal string[] _varyByControlsCollection;
internal string _varyByCustom;
internal string _sqlDependency;
internal string _provider;
internal bool _cachingDisabled;
private string _outputString;
private string _cssStyleString;
private string _cacheKey;
private CacheDependency _cacheDependency;
private PartialCachingCacheEntry _cacheEntry;
private ControlCachePolicy _cachePolicy;
private ArrayList _registeredCallDataForEventValidation;
private ArrayList _registeredStyleInfo = null;
internal const char varySeparator = ';';
internal const string varySeparatorString = ";";
internal override void InitRecursive(Control namingContainer) {
HashCodeCombiner combinedHashCode = new HashCodeCombiner();
_cacheKey = ComputeNonVaryCacheKey(combinedHashCode);
// Save the non-varying hash, so we don't need to recalculate it later
_nonVaryHashCode = combinedHashCode.CombinedHash;
PartialCachingCacheEntry cacheEntry = null;
// Check if there is a cache entry for the non-varying key
object tmpCacheEntry = OutputCache.GetFragment(_cacheKey, _provider);
if (tmpCacheEntry != null) {
ControlCachedVary cachedVary = tmpCacheEntry as ControlCachedVary;
if (cachedVary != null) {
string varyCachedKey = ComputeVaryCacheKey(combinedHashCode, cachedVary);
// Check if there is a cache entry for the varying key
cacheEntry = (PartialCachingCacheEntry) OutputCache.GetFragment(varyCachedKey, _provider);
if (cacheEntry != null && cacheEntry._cachedVaryId != cachedVary.CachedVaryId) {
cacheEntry = null;
// explicitly remove the entry
OutputCache.RemoveFragment(varyCachedKey, _provider);
}
}
else {
// If it wasn't a ControlCachedVary, it must be a PartialCachingCacheEntry
cacheEntry = (PartialCachingCacheEntry) tmpCacheEntry;
}
}
// If it's a cache miss, create the control and make it our child
if (cacheEntry == null) {
// Cache miss
_cacheEntry = new PartialCachingCacheEntry();
_cachedCtrl = CreateCachedControl();
Controls.Add(_cachedCtrl);
// Make sure the Page knows about us while the control's OnInit is called
Page.PushCachingControl(this);
base.InitRecursive(namingContainer);
Page.PopCachingControl();
}
else {
// Cache hit
_outputString = cacheEntry.OutputString;
_cssStyleString = cacheEntry.CssStyleString;
// If any calls to Register* API's were made when the control was run,
// make them now to restore correct behavior (VSWhidbey 80907)
if (cacheEntry.RegisteredClientCalls != null) {
foreach (RegisterCallData registerCallData in cacheEntry.RegisteredClientCalls) {
switch (registerCallData.Type) {
case ClientAPIRegisterType.WebFormsScript:
Page.RegisterWebFormsScript();
break;
case ClientAPIRegisterType.PostBackScript:
Page.RegisterPostBackScript();
break;
case ClientAPIRegisterType.FocusScript:
Page.RegisterFocusScript();
break;
case ClientAPIRegisterType.ClientScriptBlocks:
case ClientAPIRegisterType.ClientScriptBlocksWithoutTags:
case ClientAPIRegisterType.ClientStartupScripts:
case ClientAPIRegisterType.ClientStartupScriptsWithoutTags:
Page.ClientScript.RegisterScriptBlock(registerCallData.Key,
registerCallData.StringParam2, registerCallData.Type);
break;
case ClientAPIRegisterType.OnSubmitStatement:
Page.ClientScript.RegisterOnSubmitStatementInternal(registerCallData.Key,
registerCallData.StringParam2);
break;
case ClientAPIRegisterType.ArrayDeclaration:
Page.ClientScript.RegisterArrayDeclaration(registerCallData.StringParam1,
registerCallData.StringParam2);
break;
case ClientAPIRegisterType.HiddenField:
Page.ClientScript.RegisterHiddenField(registerCallData.StringParam1,
registerCallData.StringParam2);
break;
case ClientAPIRegisterType.ExpandoAttribute:
Page.ClientScript.RegisterExpandoAttribute(registerCallData.StringParam1,
registerCallData.StringParam2, registerCallData.StringParam3, false);
break;
case ClientAPIRegisterType.EventValidation:
if (_registeredCallDataForEventValidation == null) {
_registeredCallDataForEventValidation = new ArrayList();
}
_registeredCallDataForEventValidation.Add(registerCallData);
break;
default:
Debug.Assert(false);
break;
}
}
}
base.InitRecursive(namingContainer);
}
}
internal override void LoadRecursive() {
// If we're in a cache hit, don't do anything special
if (_outputString != null) {
base.LoadRecursive();
return;
}
// Make sure the Page knows about us while the control's OnLoad is called
Page.PushCachingControl(this);
base.LoadRecursive();
Page.PopCachingControl();
}
internal override void PreRenderRecursiveInternal() {
// If we're in a cache hit, don't do anything special
if (_outputString != null) {
base.PreRenderRecursiveInternal();
// register the cached styles on the Header control.
if (_cssStyleString != null && Page.Header != null) {
Page.Header.RegisterCssStyleString(_cssStyleString);
}
return;
}
// Make sure the Page knows about us while the control's OnPreRender is called
Page.PushCachingControl(this);
base.PreRenderRecursiveInternal();
Page.PopCachingControl();
}
/// <internalonly/>
public override void Dispose() {
if (_cacheDependency != null) {
_cacheDependency.Dispose();
_cacheDependency = null;
}
base.Dispose();
}
internal abstract Control CreateCachedControl();
/// <devdoc>
/// <para> Gets or sets the CacheDependency used to cache the control output.</para>
/// </devdoc>
public CacheDependency Dependency {
get { return _cacheDependency; }
set { _cacheDependency = value; }
}
public ControlCachePolicy CachePolicy {
get {
// Create the ControlCachePolicy object on demand
if (_cachePolicy == null)
_cachePolicy = new ControlCachePolicy(this);
return _cachePolicy;
}
}
internal HttpCacheVaryByParams VaryByParams {
get {
if (_varyByParamsCollection == null) {
_varyByParamsCollection = new HttpCacheVaryByParams();
_varyByParamsCollection.IgnoreParams = true;
}
return _varyByParamsCollection;
}
}
internal string VaryByControl {
get {
if (_varyByControlsCollection == null)
return String.Empty;
return String.Join(varySeparatorString, _varyByControlsCollection);
}
set {
if (String.IsNullOrEmpty(value)) {
_varyByControlsCollection = null;
}
else {
_varyByControlsCollection = value.Split(varySeparator);
}
}
}
internal TimeSpan Duration {
get {
// Special case MaxValue
if (_utcExpirationTime == DateTime.MaxValue)
return TimeSpan.MaxValue;
return _utcExpirationTime - DateTime.UtcNow;
}
set {
if (value == TimeSpan.MaxValue) {
// If it's the max timespan, just make it DateTime.MaxValue to avoid
// an overflow when adding (VSWhidbey 273271)
_utcExpirationTime = DateTime.MaxValue;
}
else {
// Compute the expiration time
_utcExpirationTime = DateTime.UtcNow.Add(value);
}
}
}
private void RegisterValidationEvents() {
if (_registeredCallDataForEventValidation != null) {
foreach (RegisterCallData registerCallData in _registeredCallDataForEventValidation) {
Page.ClientScript.RegisterForEventValidation(registerCallData.StringParam1,
registerCallData.StringParam2);
}
}
}
internal void RegisterStyleInfo(SelectorStyleInfo selectorInfo) {
if (_registeredStyleInfo == null) {
_registeredStyleInfo = new ArrayList();
}
_registeredStyleInfo.Add(selectorInfo);
}
/// <internalonly/>
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
protected internal override void Render(HtmlTextWriter output) {
CacheDependency sqlCacheDep = null;
// If the output is cached, use it and do nothing else
if (_outputString != null) {
output.Write(_outputString);
RegisterValidationEvents();
return;
}
// If caching was turned off, just render the control
if (_cachingDisabled || !RuntimeConfig.GetAppConfig().OutputCache.EnableFragmentCache) {
_cachedCtrl.RenderControl(output);
return;
}
// Create SQL cache dependency before we render the page
if (_sqlDependency != null) {
sqlCacheDep = SqlCacheDependency.CreateOutputCacheDependency(_sqlDependency);
}
_cacheEntry.CssStyleString = GetCssStyleRenderString(output.GetType());
// Create a new HtmlTextWriter, with the same type as the current one (see ASURT 118922)
StringWriter tmpWriter = new StringWriter();
HtmlTextWriter tmpHtmlWriter = Page.CreateHtmlTextWriterFromType(tmpWriter, output.GetType());
CacheDependency cacheDep;
TextWriter savedWriter = Context.Response.SwitchWriter(tmpWriter);
try {
// Make sure the Page knows about us while the control's OnPreRender is called
Page.PushCachingControl(this);
_cachedCtrl.RenderControl(tmpHtmlWriter);
Page.PopCachingControl();
}
finally {
Context.Response.SwitchWriter(savedWriter);
}
_cacheEntry.OutputString = tmpWriter.ToString();
// Send the output to the response
output.Write(_cacheEntry.OutputString);
// Cache the output
cacheDep = _cacheDependency;
if (sqlCacheDep != null) {
if (cacheDep == null) {
cacheDep = sqlCacheDep;
}
else {
AggregateCacheDependency aggr = new AggregateCacheDependency();
aggr.Add(cacheDep);
aggr.Add(sqlCacheDep);
cacheDep = aggr;
}
}
ControlCachedVary cachedVary = null;
string realItemCacheKey;
// If there are no varies, use the non-varying key
if (_varyByParamsCollection == null && _varyByControlsCollection == null && _varyByCustom == null) {
realItemCacheKey = _cacheKey;
}
else {
string[] varyByParams = null;
if (_varyByParamsCollection != null)
varyByParams = _varyByParamsCollection.GetParams();
cachedVary = new ControlCachedVary(varyByParams, _varyByControlsCollection, _varyByCustom);
HashCodeCombiner combinedHashCode = new HashCodeCombiner(_nonVaryHashCode);
realItemCacheKey = ComputeVaryCacheKey(combinedHashCode, cachedVary);
}
// Compute the correct expiration, sliding or absolute
DateTime utcExpirationTime;
TimeSpan slidingExpiration;
if (_useSlidingExpiration) {
utcExpirationTime = Cache.NoAbsoluteExpiration;
slidingExpiration = _utcExpirationTime - DateTime.UtcNow;
}
else {
utcExpirationTime = _utcExpirationTime;
slidingExpiration = Cache.NoSlidingExpiration;
}
try {
OutputCache.InsertFragment(_cacheKey, cachedVary,
realItemCacheKey, _cacheEntry,
cacheDep /*dependencies*/,
utcExpirationTime, slidingExpiration,
_provider);
}
catch {
if (cacheDep != null) {
cacheDep.Dispose();
}
throw;
}
}
// Return the key used to cache the output
private string ComputeNonVaryCacheKey(HashCodeCombiner combinedHashCode) {
// Create a cache key by combining various elements
// Start with the guid
combinedHashCode.AddObject(_guid);
// Make the key vary based on the type of the writer (ASURT 118922)
HttpBrowserCapabilities browserCap = Context.Request.Browser;
if (browserCap != null)
combinedHashCode.AddObject(browserCap.TagWriter);
return CacheInternal.PrefixPartialCachingControl + combinedHashCode.CombinedHashString;
}
private string ComputeVaryCacheKey(HashCodeCombiner combinedHashCode,
ControlCachedVary cachedVary) {
// Add something to the has to differentiate it from the non-vary hash.
// This is needed in case this method doesn't add anything else to the hash (VSWhidbey 194199)
combinedHashCode.AddInt(1);
// Get the request value collection
NameValueCollection reqValCollection;
HttpRequest request = Page.Request;
if (request != null && request.HttpVerb == HttpVerb.POST) {
// Bug 6129: Partial cache key should include posted form values in postbacks.
// Include both QueryString and Form values (but not Cookies or Server Variables like Request.Params does).
// Per Request.Params behavior, add QueryString values before Form values
reqValCollection = new NameValueCollection(request.QueryString);
reqValCollection.Add(request.Form);
}
else {
// Use the existing value if possible to avoid recreating a NameValueCollection
reqValCollection = Page.RequestValueCollection;
// If it's not set, get it based on the method
if (reqValCollection == null) {
reqValCollection = Page.GetCollectionBasedOnMethod(true /*dontReturnNull*/);
}
}
if (cachedVary._varyByParams != null) {
ICollection itemsToUseForHashCode;
// If '*' was specified, use all the items in the request collection.
// Otherwise, use only those specified.
if (cachedVary._varyByParams.Length == 1 && cachedVary._varyByParams[0] == "*")
itemsToUseForHashCode = reqValCollection;
else
itemsToUseForHashCode = cachedVary._varyByParams;
// Add the items and their values to compute the hash code
foreach (string varyByParam in itemsToUseForHashCode) {
// Note: we use to ignore certain system fields here (like VIEWSTATE), but decided
// not to for consistency with pahe output caching (VSWhidbey 196267, 479252)
combinedHashCode.AddCaseInsensitiveString(varyByParam);
string val = reqValCollection[varyByParam];
if (val != null)
combinedHashCode.AddObject(val);
}
}
if (cachedVary._varyByControls != null) {
// Prepend them with a prefix to make them fully qualified
string prefix;
if (NamingContainer == Page) {
// No prefix if it's the page
prefix = String.Empty;
}
else {
prefix = NamingContainer.UniqueID;
Debug.Assert(!String.IsNullOrEmpty(prefix));
prefix += IdSeparator;
}
prefix += _ctrlID + IdSeparator;
// Add all the relative vary params and their values to the hash code
foreach (string varyByParam in cachedVary._varyByControls) {
string temp = prefix + varyByParam.Trim();
combinedHashCode.AddCaseInsensitiveString(temp);
string val = reqValCollection[temp];
if (val != null)
combinedHashCode.AddObject(reqValCollection[temp]);
}
}
if (cachedVary._varyByCustom != null) {
string customString = Context.ApplicationInstance.GetVaryByCustomString(
Context, cachedVary._varyByCustom);
if (customString != null)
combinedHashCode.AddObject(customString);
}
return CacheInternal.PrefixPartialCachingControl + combinedHashCode.CombinedHashString;
}
private string GetCssStyleRenderString(Type htmlTextWriterType) {
// Nothing to do if no styles are registered.
if (_registeredStyleInfo == null) {
return null;
}
// Create an empty cssStringWriter
StringWriter cssStringWriter = new StringWriter(CultureInfo.CurrentCulture);
// Create a new HtmlTextWriter, with the same type as the current one
HtmlTextWriter cssHtmlTextWriter =
Page.CreateHtmlTextWriterFromType(cssStringWriter, htmlTextWriterType);
CssTextWriter cssWriter = new CssTextWriter(cssHtmlTextWriter);
foreach (SelectorStyleInfo si in _registeredStyleInfo) {
HtmlHead.RenderCssRule(cssWriter, si.selector, si.style, si.urlResolver);
}
// Return the css style rendered string
return cssStringWriter.ToString();
}
internal void SetVaryByParamsCollectionFromString(string varyByParams) {
Debug.Assert(_varyByParamsCollection == null);
if (varyByParams == null)
return;
string[] varyByParamsStrings = varyByParams.Split(varySeparator);
_varyByParamsCollection = new HttpCacheVaryByParams();
_varyByParamsCollection.SetParams(varyByParamsStrings);
}
internal void RegisterPostBackScript() {
RegisterClientCall(ClientAPIRegisterType.PostBackScript, String.Empty, null);
}
internal void RegisterFocusScript() {
RegisterClientCall(ClientAPIRegisterType.FocusScript, String.Empty, null);
}
internal void RegisterWebFormsScript() {
RegisterClientCall(ClientAPIRegisterType.WebFormsScript, String.Empty, null);
}
private void RegisterClientCall(ClientAPIRegisterType type,
ScriptKey scriptKey, string stringParam2) {
// Keep track of the call, in order to be able to call it again when there is a cache hit.
RegisterCallData registerCallData = new RegisterCallData();
registerCallData.Type = type;
registerCallData.Key = scriptKey;
registerCallData.StringParam2 = stringParam2;
if (_cacheEntry.RegisteredClientCalls == null)
_cacheEntry.RegisteredClientCalls = new ArrayList();
_cacheEntry.RegisteredClientCalls.Add(registerCallData);
}
private void RegisterClientCall(ClientAPIRegisterType type,
string stringParam1, string stringParam2) {
RegisterClientCall(type, stringParam1, stringParam2, null);
}
private void RegisterClientCall(ClientAPIRegisterType type,
string stringParam1, string stringParam2, string stringParam3) {
// Keep track of the call, in order to be able to call it again when there is a cache hit.
RegisterCallData registerCallData = new RegisterCallData();
registerCallData.Type = type;
registerCallData.StringParam1 = stringParam1;
registerCallData.StringParam2 = stringParam2;
registerCallData.StringParam3 = stringParam3;
if (_cacheEntry.RegisteredClientCalls == null)
_cacheEntry.RegisteredClientCalls = new ArrayList();
_cacheEntry.RegisteredClientCalls.Add(registerCallData);
}
internal void RegisterScriptBlock(ClientAPIRegisterType type, ScriptKey key, string script) {
RegisterClientCall(type, key, script);
}
internal void RegisterOnSubmitStatement(ScriptKey key, string script) {
RegisterClientCall(ClientAPIRegisterType.OnSubmitStatement, key, script);
}
internal void RegisterArrayDeclaration(string arrayName, string arrayValue) {
RegisterClientCall(ClientAPIRegisterType.ArrayDeclaration,
arrayName, arrayValue);
}
internal void RegisterHiddenField(string hiddenFieldName, string hiddenFieldInitialValue) {
RegisterClientCall(ClientAPIRegisterType.HiddenField,
hiddenFieldName, hiddenFieldInitialValue);
}
internal void RegisterExpandoAttribute(string controlID, string attributeName, string attributeValue) {
RegisterClientCall(ClientAPIRegisterType.ExpandoAttribute, controlID, attributeName, attributeValue);
}
internal void RegisterForEventValidation(string uniqueID, string argument) {
RegisterClientCall(ClientAPIRegisterType.EventValidation, uniqueID, argument);
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public class StaticPartialCachingControl : BasePartialCachingControl {
private BuildMethod _buildMethod;
/// <internalonly/>
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public StaticPartialCachingControl(string ctrlID, string guid, int duration,
string varyByParams, string varyByControls, string varyByCustom,
BuildMethod buildMethod)
:this(ctrlID, guid, duration, varyByParams, varyByControls,
varyByCustom, null, buildMethod, null)
{
}
/// <internalonly/>
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public StaticPartialCachingControl(string ctrlID, string guid, int duration,
string varyByParams, string varyByControls, string varyByCustom, string sqlDependency,
BuildMethod buildMethod)
:this(ctrlID, guid, duration, varyByParams, varyByControls,
varyByCustom, sqlDependency, buildMethod, null)
{
}
public StaticPartialCachingControl(string ctrlID, string guid, int duration,
string varyByParams, string varyByControls, string varyByCustom, string sqlDependency,
BuildMethod buildMethod, string providerName) {
_ctrlID = ctrlID;
Duration = new TimeSpan(0 /*hours*/, 0 /*mins*/, duration /*seconds*/);
SetVaryByParamsCollectionFromString(varyByParams);
if (varyByControls != null)
_varyByControlsCollection = varyByControls.Split(varySeparator);
_varyByCustom = varyByCustom;
_guid = guid;
_buildMethod = buildMethod;
_sqlDependency = sqlDependency;
_provider = providerName;
}
internal override Control CreateCachedControl() {
return _buildMethod();
}
/*
* Called by generated code (hence must be public).
* Create a StaticPartialCachingControl and add it as a child
*/
/// <internalonly/>
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
static public void BuildCachedControl(Control parent, string ctrlID, string guid,
int duration, string varyByParams, string varyByControls, string varyByCustom,
BuildMethod buildMethod) {
BuildCachedControl(parent, ctrlID, guid, duration, varyByParams,
varyByControls, varyByCustom, null, buildMethod, null);
}
/// <internalonly/>
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
static public void BuildCachedControl(Control parent, string ctrlID, string guid,
int duration, string varyByParams, string varyByControls, string varyByCustom, string sqlDependency,
BuildMethod buildMethod) {
BuildCachedControl(parent, ctrlID, guid, duration, varyByParams,
varyByControls, varyByCustom, sqlDependency, buildMethod, null);
}
static public void BuildCachedControl(Control parent, string ctrlID, string guid,
int duration, string varyByParams, string varyByControls, string varyByCustom, string sqlDependency,
BuildMethod buildMethod, string providerName) {
StaticPartialCachingControl pcc = new StaticPartialCachingControl(
ctrlID, guid, duration, varyByParams, varyByControls, varyByCustom, sqlDependency,
buildMethod, providerName);
((IParserAccessor)parent).AddParsedSubObject(pcc);
}
}
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public class PartialCachingControl : BasePartialCachingControl {
private IWebObjectFactory _objectFactory;
private Type _createCachedControlType;
private object[] _args;
public Control CachedControl { get { return _cachedCtrl; } }
internal PartialCachingControl(IWebObjectFactory objectFactory, Type createCachedControlType,
PartialCachingAttribute cacheAttrib, string cacheKey, object[] args) {
string providerName = cacheAttrib.ProviderName;
_ctrlID = cacheKey;
Duration = new TimeSpan(0 /*hours*/, 0 /*mins*/, cacheAttrib.Duration /*seconds*/);
SetVaryByParamsCollectionFromString(cacheAttrib.VaryByParams);
if (cacheAttrib.VaryByControls != null)
_varyByControlsCollection = cacheAttrib.VaryByControls.Split(varySeparator);
_varyByCustom = cacheAttrib.VaryByCustom;
_sqlDependency = cacheAttrib.SqlDependency;
if (providerName == OutputCache.ASPNET_INTERNAL_PROVIDER_NAME) {
providerName = null;
}
_provider = providerName;
_guid = cacheKey;
_objectFactory = objectFactory;
_createCachedControlType = createCachedControlType;
_args = args;
}
internal override Control CreateCachedControl() {
Control cachedControl;
if (_objectFactory != null) {
cachedControl = (Control) _objectFactory.CreateInstance();
}
else {
// Instantiate the control
cachedControl = (Control) HttpRuntime.CreatePublicInstance(_createCachedControlType, _args);
}
// If it's a user control, do some extra initialization
UserControl uc = cachedControl as UserControl;
if (uc != null)
uc.InitializeAsUserControl(Page);
cachedControl.ID = _ctrlID;
return cachedControl;
}
}
/*
* Holds param names that this cached item varies by.
*/
[Serializable]
internal class ControlCachedVary {
private Guid _cachedVaryId;
internal readonly string[] _varyByParams;
internal readonly string _varyByCustom;
internal readonly string[] _varyByControls;
internal Guid CachedVaryId { get { return _cachedVaryId; } }
internal ControlCachedVary(string[] varyByParams,
string[] varyByControls, string varyByCustom) {
_varyByParams = varyByParams;
_varyByControls = varyByControls;
_varyByCustom = varyByCustom;
_cachedVaryId = Guid.NewGuid();
}
public override bool Equals (Object obj) {
if (!(obj is ControlCachedVary))
return false;
ControlCachedVary cv = (ControlCachedVary) obj;
return _varyByCustom == cv._varyByCustom &&
StringUtil.StringArrayEquals(_varyByParams, cv._varyByParams) &&
StringUtil.StringArrayEquals(_varyByControls, cv._varyByControls);
}
public override int GetHashCode () {
HashCodeCombiner hashCodeCombiner = new HashCodeCombiner();
// We need non-randomized hash code for _varyByCustom
hashCodeCombiner.AddInt(StringUtil.GetNonRandomizedHashCode(_varyByCustom));
hashCodeCombiner.AddArray(_varyByParams);
hashCodeCombiner.AddArray(_varyByControls);
return hashCodeCombiner.CombinedHash32;
}
}
}