Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx35 / System.ServiceModel.Web / System / ServiceModel / Web / CachingParameterInspector.cs / 1305376 / CachingParameterInspector.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- using System.Collections.Generic; using System.Diagnostics; using System.Runtime; using System.Runtime.Serialization; using System.Security; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Diagnostics; using System.ServiceModel.Dispatcher; using System.Web; using System.Web.Caching; using System.Web.Configuration; using System.Web.UI; using System.ServiceModel.Activation; namespace System.ServiceModel.Web { class CachingParameterInspector : IParameterInspector { const char seperatorChar = ';'; const char escapeChar = '\\'; const char tableDbSeperatorChar = ':'; const string invalidSqlDependencyString = "Invalid Sql dependency string."; [Fx.Tag.SecurityNote(Critical = "A config object, which should not be leaked.")] [SecurityCritical] OutputCacheProfile cacheProfile; SqlDependencyInfo[] cacheDependencyInfoArray; [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.", Safe="The config object never leaves the CachingParameterInspector.")] [SecuritySafeCritical] public CachingParameterInspector(string cacheProfileName) { if (string.IsNullOrEmpty(cacheProfileName)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.CacheProfileNameNullOrEmpty)); } OutputCacheSettingsSection cacheSettings = AspNetEnvironment.Current.UnsafeGetConfigurationSection("system.web/caching/outputCacheSettings") as OutputCacheSettingsSection; if (cacheSettings == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileNotConfigured, cacheProfileName))); } this.cacheProfile = cacheSettings.OutputCacheProfiles[cacheProfileName]; if (this.cacheProfile == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileNotConfigured, cacheProfileName))); } // Validate the cacheProfile if (this.cacheProfile.Location != OutputCacheLocation.None) { // Duration must be set; Duration default value is -1 if (this.cacheProfile.Duration == -1) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileValueMissing, this.cacheProfile.Name, "Duration"))); } if (this.cacheProfile.VaryByParam == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileValueMissing, this.cacheProfile.Name, "VaryByParam"))); } } if (string.Equals(this.cacheProfile.SqlDependency, "CommandNotification", StringComparison.OrdinalIgnoreCase)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.CommandNotificationSqlDependencyNotSupported)); } if (!string.IsNullOrEmpty(this.cacheProfile.SqlDependency)) { ParseSqlDependencyString(cacheProfile.SqlDependency); } } [Fx.Tag.SecurityNote(Critical = "Handles config objects, which should not be leaked.", Safe = "The config object never leaves the CachingParameterInspector.")] [SecuritySafeCritical] public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState) { if (this.cacheProfile != null && this.cacheProfile.Enabled && OperationContext.Current.IncomingMessage.Version == MessageVersion.None) { if (DiagnosticUtility.ShouldTraceWarning && !IsAnonymous()) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.AddingAuthenticatedResponseToOutputCache, SR2.GetString(SR2.TraceCodeAddingAuthenticatedResponseToOutputCache, operationName)); } else if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.AddingResponseToOutputCache, SR2.GetString(SR2.TraceCodeAddingResponseToOutputCache, operationName)); } SetCacheFromCacheProfile(); } } public object BeforeCall(string operationName, object[] inputs) { return null; } bool IsAnonymous() { if (HttpContext.Current.User.Identity.IsAuthenticated) { return false; } else { if (OperationContext.Current.ServiceSecurityContext == null) { return true; } else { return OperationContext.Current.ServiceSecurityContext.IsAnonymous; } } } static SqlDependencyInfo[] ParseSqlDependencyString(string sqlDependencyString) { // The code for this method was taken from private code in // System.Web.SqlCacheDependency.ParseSql7OutputCacheDependency. // Alter if only absolutely necessary since we want to reproduce the same ASP.NET caching behavior. ListdependencyList = new List (); bool escapeSequenceFlag = false; int startIndexForDatabaseName = 0; int startIndexForTableName = -1; string databaseName = null; try { for (int currentIndex = 0; currentIndex < (sqlDependencyString.Length + 1); currentIndex++) { if (escapeSequenceFlag) { escapeSequenceFlag = false; } else if ((currentIndex != sqlDependencyString.Length) && (sqlDependencyString[currentIndex] == escapeChar)) { escapeSequenceFlag = true; } else { int subStringLength; if ((currentIndex == sqlDependencyString.Length) || (sqlDependencyString[currentIndex] == seperatorChar)) { if (databaseName == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(invalidSqlDependencyString); } subStringLength = currentIndex - startIndexForTableName; if (subStringLength == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(invalidSqlDependencyString); } string tableName = sqlDependencyString.Substring(startIndexForTableName, subStringLength); SqlDependencyInfo info = new SqlDependencyInfo(); info.Database = VerifyAndRemoveEscapeCharacters(databaseName); info.Table = VerifyAndRemoveEscapeCharacters(tableName); dependencyList.Add(info); startIndexForDatabaseName = currentIndex + 1; databaseName = null; } if (currentIndex == sqlDependencyString.Length) { break; } if (sqlDependencyString[currentIndex] == tableDbSeperatorChar) { if (databaseName != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(invalidSqlDependencyString); } subStringLength = currentIndex - startIndexForDatabaseName; if (subStringLength == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(invalidSqlDependencyString); } databaseName = sqlDependencyString.Substring(startIndexForDatabaseName, subStringLength); startIndexForTableName = currentIndex + 1; } } } } catch (ArgumentException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileSqlDependencyIsInvalid, sqlDependencyString))); } if (dependencyList.Count == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.CacheProfileSqlDependencyIsInvalid, sqlDependencyString))); } return dependencyList.ToArray(); } static string VerifyAndRemoveEscapeCharacters(string str) { // The code for this method was taken from private code in // System.Web.SqlCacheDependency.VerifyAndRemoveEscapeCharacters. // Alter if only absolutely necessary since we want to reproduce the same ASP.NET caching behavior. bool escapeSequenceFlag = false; for (int currentIndex = 0; currentIndex < str.Length; currentIndex++) { if (escapeSequenceFlag) { if (((str[currentIndex] != escapeChar) && (str[currentIndex] != tableDbSeperatorChar)) && (str[currentIndex] != seperatorChar)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(str); } escapeSequenceFlag = false; } else if (str[currentIndex] == escapeChar) { if ((currentIndex + 1) == str.Length) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(str); } escapeSequenceFlag = true; str = str.Remove(currentIndex, 1); currentIndex--; } } return str; } CacheDependency CreateSingleCacheDependency(string sqlDependency) { if (this.cacheDependencyInfoArray == null) { this.cacheDependencyInfoArray = CachingParameterInspector.ParseSqlDependencyString(sqlDependency); } // cacheDependencyInfoArray will never have length = 0 if (this.cacheDependencyInfoArray.Length == 1) { return new SqlCacheDependency(this.cacheDependencyInfoArray[0].Database, this.cacheDependencyInfoArray[0].Table); } AggregateCacheDependency cacheDependency = new AggregateCacheDependency(); foreach (SqlDependencyInfo dependencyInfo in this.cacheDependencyInfoArray) { cacheDependency.Add(new CacheDependency[] { new SqlCacheDependency(dependencyInfo.Database, dependencyInfo.Table) }); } return cacheDependency; } [Fx.Tag.SecurityNote(Critical = "Uses config object to set properties of the HttpCachePolicy.", Safe = "The config object itself doesn't leak.")] [SecuritySafeCritical] void SetCacheFromCacheProfile() { HttpCachePolicy cache = HttpContext.Current.Response.Cache; if (this.cacheProfile.NoStore) { cache.SetNoStore(); } // Location is not required to be set in the config. The default is Any, // but if it is not set in the config the value will be -1. So must correct for this. if ((int)(this.cacheProfile.Location) == -1) { cache.SetCacheability(HttpCacheability.Public); } else { switch (this.cacheProfile.Location) { case OutputCacheLocation.Any: cache.SetCacheability(HttpCacheability.Public); break; case OutputCacheLocation.Client: cache.SetCacheability(HttpCacheability.Private); break; case OutputCacheLocation.Downstream: cache.SetCacheability(HttpCacheability.Public); cache.SetNoServerCaching(); break; case OutputCacheLocation.None: cache.SetCacheability(HttpCacheability.NoCache); break; case OutputCacheLocation.Server: cache.SetCacheability(HttpCacheability.ServerAndNoCache); break; case OutputCacheLocation.ServerAndClient: cache.SetCacheability(HttpCacheability.ServerAndPrivate); break; default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.CacheProfileLocationNotSupported, this.cacheProfile.Location))); } } if (this.cacheProfile.Location != OutputCacheLocation.None) { cache.SetExpires(HttpContext.Current.Timestamp.AddSeconds((double)this.cacheProfile.Duration)); cache.SetMaxAge(new TimeSpan(0, 0, this.cacheProfile.Duration)); cache.SetValidUntilExpires(true); cache.SetLastModified(HttpContext.Current.Timestamp); if (this.cacheProfile.Location != OutputCacheLocation.Client) { if (!string.IsNullOrEmpty(this.cacheProfile.VaryByContentEncoding)) { foreach (string contentEncoding in this.cacheProfile.VaryByContentEncoding.Split(seperatorChar)) { cache.VaryByContentEncodings[contentEncoding.Trim()] = true; } } if (!string.IsNullOrEmpty(this.cacheProfile.VaryByHeader)) { foreach (string header in this.cacheProfile.VaryByHeader.Split(seperatorChar)) { cache.VaryByHeaders[header.Trim()] = true; } } if (this.cacheProfile.Location != OutputCacheLocation.Downstream) { if (!string.IsNullOrEmpty(this.cacheProfile.VaryByCustom)) { cache.SetVaryByCustom(this.cacheProfile.VaryByCustom); } if (!string.IsNullOrEmpty(this.cacheProfile.VaryByParam)) { foreach (string parameter in cacheProfile.VaryByParam.Split(seperatorChar)) { cache.VaryByParams[parameter.Trim()] = true; } } if (!string.IsNullOrEmpty(this.cacheProfile.SqlDependency)) { CacheDependency cacheDependency = this.CreateSingleCacheDependency(cacheProfile.SqlDependency); HttpContext.Current.Response.AddCacheDependency(new CacheDependency[] { cacheDependency }); } } } } } private struct SqlDependencyInfo { public string Database; public string Table; } } } // 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
- RoleGroupCollection.cs
- GradientBrush.cs
- RegionIterator.cs
- CompilationSection.cs
- QueryInterceptorAttribute.cs
- SystemTcpConnection.cs
- PerfCounterSection.cs
- DynamicExpression.cs
- UtilityExtension.cs
- MetaData.cs
- StructuredType.cs
- UserPersonalizationStateInfo.cs
- Utilities.cs
- Types.cs
- FastPropertyAccessor.cs
- WebBrowserBase.cs
- ReferenceEqualityComparer.cs
- TextSpanModifier.cs
- OleDbConnection.cs
- DataKeyCollection.cs
- WsdlServiceChannelBuilder.cs
- TypeValidationEventArgs.cs
- AssociatedControlConverter.cs
- EnlistmentState.cs
- AspNetRouteServiceHttpHandler.cs
- TextUtf8RawTextWriter.cs
- CombinedGeometry.cs
- Page.cs
- DocumentXPathNavigator.cs
- BitConverter.cs
- MouseGestureValueSerializer.cs
- SkipStoryboardToFill.cs
- Int64.cs
- _ConnectionGroup.cs
- EntityDataSourceWrapper.cs
- ExpressionEditorAttribute.cs
- DataGridViewRowPrePaintEventArgs.cs
- Lazy.cs
- CodeTypeParameterCollection.cs
- Attributes.cs
- KeyFrames.cs
- TextTrailingWordEllipsis.cs
- MissingFieldException.cs
- TypeDefinition.cs
- IPHostEntry.cs
- ResolveNameEventArgs.cs
- UIElement.cs
- AssemblyHash.cs
- StrongNameKeyPair.cs
- LocalizabilityAttribute.cs
- Console.cs
- ListViewItem.cs
- codemethodreferenceexpression.cs
- FixedDocumentPaginator.cs
- DataGridViewRowCollection.cs
- CallbackTimeoutsBehavior.cs
- WorkflowOperationAsyncResult.cs
- XmlDataLoader.cs
- PasswordBox.cs
- UniqueEventHelper.cs
- documentsequencetextpointer.cs
- Int32CollectionConverter.cs
- TabControlEvent.cs
- IisTraceListener.cs
- ConnectionString.cs
- StyleHelper.cs
- MenuCommandsChangedEventArgs.cs
- WebPartDisplayModeEventArgs.cs
- ElementUtil.cs
- SAPICategories.cs
- XmlValidatingReaderImpl.cs
- ApplicationManager.cs
- DataColumn.cs
- PrinterSettings.cs
- SHA1.cs
- SingleKeyFrameCollection.cs
- TypeInfo.cs
- ReadOnlyPermissionSet.cs
- CTreeGenerator.cs
- HtmlDocument.cs
- FactoryRecord.cs
- TableLayoutPanelResizeGlyph.cs
- StylusShape.cs
- SkewTransform.cs
- Stack.cs
- DWriteFactory.cs
- ReadOnlyNameValueCollection.cs
- ResXDataNode.cs
- LinearGradientBrush.cs
- CommandEventArgs.cs
- CheckBoxBaseAdapter.cs
- WindowsPen.cs
- XmlSortKeyAccumulator.cs
- ActivityExecutionFilter.cs
- ScriptDescriptor.cs
- BinaryNode.cs
- BitmapEncoder.cs
- ChangeDirector.cs
- TextTreeTextBlock.cs
- HttpWebRequest.cs