WebPartPersonalization.cs source code in C# .NET

Source code for the .NET framework in C#

                        

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 / WebParts / WebPartPersonalization.cs / 1 / WebPartPersonalization.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.WebControls.WebParts { 
 
    using System;
    using System.Collections; 
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Configuration;
    using System.Configuration.Provider; 
    using System.Security.Permissions;
    using System.Security.Principal; 
    using System.Web; 
    using System.Web.Configuration;
    using System.Web.UI; 
    using System.Web.Util;
    using System.Web.Hosting;

    [TypeConverterAttribute(typeof(EmptyStringExpandableObjectConverter))] 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] 
    public class WebPartPersonalization { 

        public static readonly WebPartUserCapability ModifyStateUserCapability = new WebPartUserCapability("modifyState"); 
        public static readonly WebPartUserCapability EnterSharedScopeUserCapability = new WebPartUserCapability("enterSharedScope");

        private WebPartManager _owner;
 
        // Properties
        private bool _enabled; 
        private string _providerName; 
        private PersonalizationScope _initialScope;
 
        // Computed state
        private bool _initialized;
        private bool _initializedSet;
        private PersonalizationProvider _provider; 
        private PersonalizationScope _currentScope;
        private IDictionary _userCapabilities; 
        private PersonalizationState _personalizationState; 
        private bool _scopeToggled;
        private bool _shouldResetPersonalizationState; 

        /// 
        /// 
        public WebPartPersonalization(WebPartManager owner) { 
            if (owner == null) {
                throw new ArgumentNullException("owner"); 
            } 

            _owner = owner; 

            _enabled = true;
        }
 
        /// 
        /// Indicates whether the current user has the permissions to switch 
        /// into shared personalization scope. 
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public bool CanEnterSharedScope { 
            get {
                // We cannot cache this value, since UserCapabilities is protected virtual, 
                // and could return a different value at any time 
                IDictionary userCapabilities = UserCapabilities;
                bool canEnterSharedScope = (userCapabilities != null) && 
                    (userCapabilities.Contains(WebPartPersonalization.EnterSharedScopeUserCapability));
                return canEnterSharedScope;
            }
        } 

        ///  
        ///  
        [
        DefaultValue(true), 
        NotifyParentProperty(true),
        WebSysDescription(SR.WebPartPersonalization_Enabled)
        ]
        public virtual bool Enabled { 
            get {
                return _enabled; 
            } 
            set {
                if (!WebPartManager.DesignMode && _initializedSet && (value != Enabled)) { 
                    throw new InvalidOperationException(
                        SR.GetString(SR.WebPartPersonalization_MustSetBeforeInit, "Enabled", "WebPartPersonalization"));
                }
 
                _enabled = value;
            } 
        } 

        // Returns true if the current user in the current scope on the current page has personalization data 
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public virtual bool HasPersonalizationState {
            get { 
                if (_provider == null) { 
                    throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CantUsePropertyBeforeInit,
                                                        "HasPersonalizationState", "WebPartPersonalization")); 
                }

                Page page = WebPartManager.Page;
                if (page == null) { 
                    throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
                } 
 
                HttpRequest request = page.RequestInternal;
                if (request == null) { 
                    throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page.Request"));
                }

                PersonalizationStateQuery query = new PersonalizationStateQuery(); 
                query.PathToMatch = request.AppRelativeCurrentExecutionFilePath;
                if (Scope == PersonalizationScope.User && request.IsAuthenticated) { 
                    query.UsernameToMatch = page.User.Identity.Name; 
                }
 
                return (_provider.GetCountOfState(Scope, query) > 0);
            }
        }
 
        /// 
        /// Allows changing the initial personalization scope that is given 
        /// preference when requesting the page on its first request. 
        /// This must be set before personalization data is loaded into the
        /// WebPartManager. 
        /// 
        [
        DefaultValue(PersonalizationScope.User),
        NotifyParentProperty(true), 
        WebSysDescription(SR.WebPartPersonalization_InitialScope)
        ] 
        public virtual PersonalizationScope InitialScope { 
            get {
                return _initialScope; 
            }
            set {
                if ((value < PersonalizationScope.User) || (value > PersonalizationScope.Shared)) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
 
                if (!WebPartManager.DesignMode && _initializedSet && (value != InitialScope)) { 
                    throw new InvalidOperationException(
                        SR.GetString(SR.WebPartPersonalization_MustSetBeforeInit, "InitialScope", "WebPartPersonalization")); 
                }

                _initialScope = value;
            } 
        }
 
        ///  
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public bool IsEnabled { 
            get {
                return IsInitialized; 
            } 
        }
 
        /// 
        /// Indicates whether personalization state has been loaded. Properties of this
        /// object cannot be saved once this object is initialized.
        ///  
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        protected bool IsInitialized { 
            get {
                return _initialized;
            }
        } 

        ///  
        /// Determines if personalization and the ability to modify personalization state is enabled 
        /// in the current request. This depends on whether a user is authenticated for this request,
        /// and if that user has the rights to modify personalization state. 
        /// To check if just personalization is enabled at all, the IsEnabled property
        /// should be used.
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ] 
        public bool IsModifiable {
            get { 
                // We cannot cache this value, since UserCapabilities is protected virtual,
                // and could return a different value at any time
                IDictionary userCapabilities = UserCapabilities;
                bool isModifiable = (userCapabilities != null) && 
                    (userCapabilities.Contains(WebPartPersonalization.ModifyStateUserCapability));
                return isModifiable; 
            } 
        }
 
        /// 
        /// 
        [
        DefaultValue(""), 
        NotifyParentProperty(true),
        WebSysDescription(SR.WebPartPersonalization_ProviderName) 
        ] 
        public virtual string ProviderName {
            get { 
                return (_providerName != null) ? _providerName : String.Empty;
            }
            set {
                if (!WebPartManager.DesignMode && _initializedSet && 
                    !String.Equals(value, ProviderName, StringComparison.Ordinal)) {
                    throw new InvalidOperationException( 
                        SR.GetString(SR.WebPartPersonalization_MustSetBeforeInit, "ProviderName", "WebPartPersonalization")); 
                }
 
                _providerName = value;
            }
        }
 
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public PersonalizationScope Scope { 
            get {
                return _currentScope;
            }
        } 

        internal bool ScopeToggled { 
            get { 
                return _scopeToggled;
            } 
        }

        // True if the personalization data was reset this request.  If so, we will not save data
        // at the end of the request. 
        protected bool ShouldResetPersonalizationState {
            get { 
                return _shouldResetPersonalizationState; 
            }
            set { 
                _shouldResetPersonalizationState = value;
            }
        }
 
        protected virtual IDictionary UserCapabilities {
            get { 
                if (_userCapabilities == null) { 
                    _userCapabilities = new HybridDictionary();
                } 
                return _userCapabilities;
            }
        }
 
        protected WebPartManager WebPartManager {
            get { 
                return _owner; 
            }
        } 

        /// 
        /// 
        protected internal virtual void ApplyPersonalizationState() { 
            if (IsEnabled) {
                EnsurePersonalizationState(); 
                _personalizationState.ApplyWebPartManagerPersonalization(); 
            }
        } 

        /// 
        /// 
        protected internal virtual void ApplyPersonalizationState(WebPart webPart) { 
            if (webPart == null) {
                throw new ArgumentNullException("webPart"); 
            } 

            if (IsEnabled) { 
                EnsurePersonalizationState();
                _personalizationState.ApplyWebPartPersonalization(webPart);
            }
        } 

        // Helper method used by CopyPersonalizationState() 
        private void ApplyPersonalizationState(Control control, PersonalizationInfo info) { 
            ITrackingPersonalizable trackingPersonalizable = control as ITrackingPersonalizable;
            IPersonalizable customPersonalizable = control as IPersonalizable; 

            if (trackingPersonalizable != null) {
                trackingPersonalizable.BeginLoad();
            } 

            // If customPersonalizable is null, then info.CustomProperties should also be null 
            Debug.Assert(!(customPersonalizable == null && info.CustomProperties != null)); 

            if (customPersonalizable != null && info.CustomProperties != null && info.CustomProperties.Count > 0) { 
                customPersonalizable.Load(info.CustomProperties);
            }

            if (info.Properties != null && info.Properties.Count > 0) { 
                BlobPersonalizationState.SetPersonalizedProperties(control, info.Properties);
            } 
 
            if (trackingPersonalizable != null) {
                trackingPersonalizable.EndLoad(); 
            }
        }

        protected virtual void ChangeScope(PersonalizationScope scope) { 
            PersonalizationProviderHelper.CheckPersonalizationScope(scope);
 
            if (scope == _currentScope) { 
                return;
            } 

            if ((scope == PersonalizationScope.Shared) && (!CanEnterSharedScope)) {
                throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CannotEnterSharedScope));
            } 

            _currentScope = scope; 
            _scopeToggled = true; 
        }
 
        // Extracts the personalization state from webPartA, and applies it to webPartB.
        // Assumes that webPartA and webPartB are the same type.  If the WebParts are GenericWebParts,
        // then copies the personalization state from the ChildControl of webPartA to the
        // ChildControl of webPartB. 
        protected internal virtual void CopyPersonalizationState(WebPart webPartA, WebPart webPartB) {
            if (webPartA == null) { 
                throw new ArgumentNullException("webPartA"); 
            }
            if (webPartB == null) { 
                throw new ArgumentNullException("webPartB");
            }
            if (webPartA.GetType() != webPartB.GetType()) {
                throw new ArgumentException(SR.GetString( 
                    SR.WebPartPersonalization_SameType, "webPartA", "webPartB"));
            } 
 
            CopyPersonalizationState((Control)webPartA, (Control)webPartB);
 
            GenericWebPart genericWebPartA = webPartA as GenericWebPart;
            GenericWebPart genericWebPartB = webPartB as GenericWebPart;
            // Assert that the GenericWebParts are either both null or both non-null
            Debug.Assert((genericWebPartA == null) == (genericWebPartB == null)); 
            if (genericWebPartA != null && genericWebPartB != null) {
                Control childControlA = genericWebPartA.ChildControl; 
                Control childControlB = genericWebPartB.ChildControl; 

                if (childControlA == null) { 
                    throw new ArgumentException(SR.GetString(
                        SR.PropertyCannotBeNull, "ChildControl"), "webPartA");
                }
                if (childControlB == null) { 
                    throw new ArgumentException(SR.GetString(
                        SR.PropertyCannotBeNull, "ChildControl"), "webPartB"); 
                } 
                if (childControlA.GetType() != childControlB.GetType()) {
                    throw new ArgumentException(SR.GetString( 
                        SR.WebPartPersonalization_SameType, "webPartA.ChildControl", "webPartB.ChildControl"));
                }

                CopyPersonalizationState(childControlA, childControlB); 
            }
 
            // IPersonalizable.IsDirty should always be false on the new WebPart, since the only data 
            // on the new WebPart was loaded via personalization, which should not cause the control
            // to be dirty.  However, we want to save the IPersonalizable data on this request, so 
            // we call SetDirty() to force the IPersonalizable data to be saved.
            SetDirty(webPartB);
        }
 
        private void CopyPersonalizationState(Control controlA, Control controlB) {
            PersonalizationInfo info = ExtractPersonalizationState(controlA); 
            ApplyPersonalizationState(controlB, info); 
        }
 
        /// 
        /// 
        private void DeterminePersonalizationProvider() {
            string providerName = ProviderName; 
            if (String.IsNullOrEmpty(providerName)) {
                // Use the default provider 
                _provider = PersonalizationAdministration.Provider; 
                // The default provider can never be null
                Debug.Assert(_provider != null); 
            }
            else {
                // Look for a provider with the specified name
                PersonalizationProvider provider = PersonalizationAdministration.Providers[providerName]; 
                if (provider != null) {
                    _provider = provider; 
                } 
                else {
                    throw new ProviderException( 
                        SR.GetString(SR.WebPartPersonalization_ProviderNotFound, providerName));
                }
            }
        } 

        ///  
        ///  
        public void EnsureEnabled(bool ensureModifiable) {
            bool value = (ensureModifiable ? IsModifiable : IsEnabled); 

            if (!value) {
                string message;
                if (ensureModifiable) { 
                    message = SR.GetString(SR.WebPartPersonalization_PersonalizationNotModifiable);
                } 
                else { 
                    message = SR.GetString(SR.WebPartPersonalization_PersonalizationNotEnabled);
                } 
                throw new InvalidOperationException(message);
            }
        }
 
        private void EnsurePersonalizationState() {
            if (_personalizationState == null) { 
                throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_PersonalizationStateNotLoaded)); 
            }
        } 

        /// 
        /// 
        protected internal virtual void ExtractPersonalizationState() { 
            // If we reset the personalization data on this request, we should not extract data since
            // it will not be saved. 
            if (IsEnabled && !ShouldResetPersonalizationState) { 
                EnsurePersonalizationState();
                _personalizationState.ExtractWebPartManagerPersonalization(); 
            }
        }

        ///  
        /// 
        protected internal virtual void ExtractPersonalizationState(WebPart webPart) { 
            // If we reset the personalization data on this request, we should not extract data since 
            // it will not be saved.
            if (IsEnabled && !ShouldResetPersonalizationState) { 
                EnsurePersonalizationState();
                _personalizationState.ExtractWebPartPersonalization(webPart);
            }
        } 

        // Helper method used by CopyPersonalizationState() 
        private PersonalizationInfo ExtractPersonalizationState(Control control) { 
            ITrackingPersonalizable trackingPersonalizable = control as ITrackingPersonalizable;
            IPersonalizable customPersonalizable = control as IPersonalizable; 

            if (trackingPersonalizable != null) {
                trackingPersonalizable.BeginSave();
            } 

            PersonalizationInfo info = new PersonalizationInfo(); 
            if (customPersonalizable != null) { 
                info.CustomProperties = new PersonalizationDictionary();
                customPersonalizable.Save(info.CustomProperties); 
            }
            info.Properties = BlobPersonalizationState.GetPersonalizedProperties(control, PersonalizationScope.Shared);

            if (trackingPersonalizable != null) { 
                trackingPersonalizable.EndSave();
            } 
 
            return info;
        } 

        // Returns the AuthorizationFilter string for a WebPart before it is instantiated
        // Returns null if there is no personalized value for AuthorizationFilter
        protected internal virtual string GetAuthorizationFilter(string webPartID) { 
            if (String.IsNullOrEmpty(webPartID)) {
                throw ExceptionUtil.ParameterNullOrEmpty("webPartID"); 
            } 

            EnsureEnabled(false); 
            EnsurePersonalizationState();
            return _personalizationState.GetAuthorizationFilter(webPartID);
        }
 
        /// 
        ///  
        internal void LoadInternal() { 
            if (Enabled) {
                _currentScope = Load(); 
                _initialized = true;
            }
            _initializedSet = true;
        } 

        ///  
        /// Loads personalization information from its storage, and computes the initial personalization 
        /// scope. This method determines the provider type to be used, and the current user's capabilities.
        ///  
        protected virtual PersonalizationScope Load() {
            if (!Enabled) {
                throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_PersonalizationNotEnabled));
            } 

            // Determine the provider early, as it is needed to continue execution. 
            // Provider is used to detect user's capabilities, load personalization state 
            // and determine initial scope.
            DeterminePersonalizationProvider(); 
            Debug.Assert(_provider != null);

            Page page = WebPartManager.Page;
            if (page == null) { 
                throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
            } 
 
            HttpRequest request = page.RequestInternal;
            if (request == null) { 
                throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page.Request"));
            }

            // Ask the provider to load information about what are the capabilities of 
            // the current user
            if (request.IsAuthenticated) { 
                _userCapabilities = _provider.DetermineUserCapabilities(WebPartManager); 
            }
 
            // A derived WebPartPersonalization can have ignoreCurrentUser to be true.
            _personalizationState = _provider.LoadPersonalizationState(WebPartManager, /* ignoreCurrentUser */ false);
            if (_personalizationState == null) {
                // We can't assume that _personalizationState will be non-null, because 
                // it depends on the provider implementation.
                throw new ProviderException(SR.GetString(SR.WebPartPersonalization_CannotLoadPersonalization)); 
            } 

            return _provider.DetermineInitialScope(WebPartManager, _personalizationState); 
        }

        // Resets the personalization data for the current user in the current scope on the current page
        public virtual void ResetPersonalizationState() { 
            EnsureEnabled(/* ensureModifiable */ true);
 
            if (_provider == null) { 
                throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CantCallMethodBeforeInit,
                                                    "ResetPersonalizationState", "WebPartPersonalization")); 
            }

            _provider.ResetPersonalizationState(WebPartManager);
            ShouldResetPersonalizationState = true; 

            Page page = WebPartManager.Page; 
            if (page == null) { 
                throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
            } 

            // Transfer execution to a new instance of the same page.  The new page will execute
            // after personalization data has been reset.
            TransferToCurrentPage(page); 
        }
 
        ///  
        /// 
        internal void SaveInternal() { 
            if (IsModifiable) {
                Save();
            }
        } 

        ///  
        /// Saves personalization information back to its storage if necessary. 
        /// 
        protected virtual void Save() { 
            EnsureEnabled(/* ensureModifiable */ true);

            EnsurePersonalizationState();
 
            if (_provider == null) {
                throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CantCallMethodBeforeInit, 
                                                    "Save", "WebPartPersonalization")); 
            }
 
            // If we reset the personalization data on this request, we should not save data to the
            // DB on this request.  It is likely we would not save data anyway, since the data probably
            // did not change since the last request, but there are some scenarios where the data could
            // have changed (like a WebPart using personalization as a cache). 
            if (_personalizationState.IsDirty && !ShouldResetPersonalizationState) {
                _provider.SavePersonalizationState(_personalizationState); 
            } 
        }
 
        /// 
        /// 
        protected internal virtual void SetDirty() {
            if (IsEnabled) { 
                EnsurePersonalizationState();
                _personalizationState.SetWebPartManagerDirty(); 
            } 
        }
 
        /// 
        /// 
        protected internal virtual void SetDirty(WebPart webPart) {
            if (IsEnabled) { 
                EnsurePersonalizationState();
                _personalizationState.SetWebPartDirty(webPart); 
            } 
        }
 
        /// 
        /// 
        public virtual void ToggleScope() {
            EnsureEnabled(/* ensureModifiable */ false); 

            Page page = WebPartManager.Page; 
            if (page == null) { 
                throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
            } 
            if (page.IsExportingWebPart) {
                // If the page is exporting, the page determines the desired scope, and it is not meaningful
                // to toggle the scope. Note that we no-op the call, rather than throwing because
                // that would require exposing a CanToggleScope property, require page developers 
                // to check for it. Furthermore, we don't guarantee ToggleScope does toggle
                // (eg. in the case of absense of user capability to enter shared scope), so 
                // simply no-op'ing isn't terribly bad... 
                return;
            } 

            Page previousPage = page.PreviousPage;
            if ((previousPage != null) &&
                (previousPage.IsCrossPagePostBack == false)) { 
                WebPartManager previousWebPartManager = WebPartManager.GetCurrentWebPartManager(previousPage);
 
                if ((previousWebPartManager != null) && (previousWebPartManager.Personalization.ScopeToggled)) { 
                    // Looks like some sort of infinite recursion is going on
                    // and we're toggling again. Like the previous case, we're 
                    // going to no-op and protect ourselves from bad code...
                    return;
                }
            } 

            if (_currentScope == PersonalizationScope.Shared) { 
                ChangeScope(PersonalizationScope.User); 
            }
            else { 
                ChangeScope(PersonalizationScope.Shared);
            }

            // Transfer execution to a new instance of the same page.  The new page will detect the scope 
            // it should run in, when it begins to load personalization data.
            TransferToCurrentPage(page); 
        } 

        // Transfers execution to a new instance of the same page. We need to clear the form collection, 
        // since it should not carry over to the page in the new scope (i.e. ViewState). If the form
        // method is GET, then we must not include the query string, since the entire form collection
        // is in the query string.  If the form method is POST (or there is no form), then we must
        // include the query string, since the developer could be using the query string to drive the 
        // logic of their page (VSWhidbey 444385 and 527117).
        private void TransferToCurrentPage(Page page) { 
            HttpRequest request = page.RequestInternal; 
            if (request == null) {
                throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page.Request")); 
            }

            string path = request.CurrentExecutionFilePath;
            if (page.Form == null || String.Equals(page.Form.Method, "post", StringComparison.OrdinalIgnoreCase)) { 
                string queryString = page.ClientQueryString;
                if (!String.IsNullOrEmpty(queryString)) { 
                    path += "?" + queryString; 
                }
            } 

            IScriptManager scriptManager = page.ScriptManager;
            if ((scriptManager != null) && scriptManager.IsInAsyncPostBack) {
                request.Response.Redirect(path); 
            }
            else { 
                page.Server.Transfer(path, /* preserveForm */ false); 
            }
        } 

        private sealed class PersonalizationInfo {
            public IDictionary Properties;
            public PersonalizationDictionary CustomProperties; 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.WebControls.WebParts { 
 
    using System;
    using System.Collections; 
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Configuration;
    using System.Configuration.Provider; 
    using System.Security.Permissions;
    using System.Security.Principal; 
    using System.Web; 
    using System.Web.Configuration;
    using System.Web.UI; 
    using System.Web.Util;
    using System.Web.Hosting;

    [TypeConverterAttribute(typeof(EmptyStringExpandableObjectConverter))] 
    [AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)] 
    public class WebPartPersonalization { 

        public static readonly WebPartUserCapability ModifyStateUserCapability = new WebPartUserCapability("modifyState"); 
        public static readonly WebPartUserCapability EnterSharedScopeUserCapability = new WebPartUserCapability("enterSharedScope");

        private WebPartManager _owner;
 
        // Properties
        private bool _enabled; 
        private string _providerName; 
        private PersonalizationScope _initialScope;
 
        // Computed state
        private bool _initialized;
        private bool _initializedSet;
        private PersonalizationProvider _provider; 
        private PersonalizationScope _currentScope;
        private IDictionary _userCapabilities; 
        private PersonalizationState _personalizationState; 
        private bool _scopeToggled;
        private bool _shouldResetPersonalizationState; 

        /// 
        /// 
        public WebPartPersonalization(WebPartManager owner) { 
            if (owner == null) {
                throw new ArgumentNullException("owner"); 
            } 

            _owner = owner; 

            _enabled = true;
        }
 
        /// 
        /// Indicates whether the current user has the permissions to switch 
        /// into shared personalization scope. 
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public bool CanEnterSharedScope { 
            get {
                // We cannot cache this value, since UserCapabilities is protected virtual, 
                // and could return a different value at any time 
                IDictionary userCapabilities = UserCapabilities;
                bool canEnterSharedScope = (userCapabilities != null) && 
                    (userCapabilities.Contains(WebPartPersonalization.EnterSharedScopeUserCapability));
                return canEnterSharedScope;
            }
        } 

        ///  
        ///  
        [
        DefaultValue(true), 
        NotifyParentProperty(true),
        WebSysDescription(SR.WebPartPersonalization_Enabled)
        ]
        public virtual bool Enabled { 
            get {
                return _enabled; 
            } 
            set {
                if (!WebPartManager.DesignMode && _initializedSet && (value != Enabled)) { 
                    throw new InvalidOperationException(
                        SR.GetString(SR.WebPartPersonalization_MustSetBeforeInit, "Enabled", "WebPartPersonalization"));
                }
 
                _enabled = value;
            } 
        } 

        // Returns true if the current user in the current scope on the current page has personalization data 
        [
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ] 
        public virtual bool HasPersonalizationState {
            get { 
                if (_provider == null) { 
                    throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CantUsePropertyBeforeInit,
                                                        "HasPersonalizationState", "WebPartPersonalization")); 
                }

                Page page = WebPartManager.Page;
                if (page == null) { 
                    throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
                } 
 
                HttpRequest request = page.RequestInternal;
                if (request == null) { 
                    throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page.Request"));
                }

                PersonalizationStateQuery query = new PersonalizationStateQuery(); 
                query.PathToMatch = request.AppRelativeCurrentExecutionFilePath;
                if (Scope == PersonalizationScope.User && request.IsAuthenticated) { 
                    query.UsernameToMatch = page.User.Identity.Name; 
                }
 
                return (_provider.GetCountOfState(Scope, query) > 0);
            }
        }
 
        /// 
        /// Allows changing the initial personalization scope that is given 
        /// preference when requesting the page on its first request. 
        /// This must be set before personalization data is loaded into the
        /// WebPartManager. 
        /// 
        [
        DefaultValue(PersonalizationScope.User),
        NotifyParentProperty(true), 
        WebSysDescription(SR.WebPartPersonalization_InitialScope)
        ] 
        public virtual PersonalizationScope InitialScope { 
            get {
                return _initialScope; 
            }
            set {
                if ((value < PersonalizationScope.User) || (value > PersonalizationScope.Shared)) {
                    throw new ArgumentOutOfRangeException("value"); 
                }
 
                if (!WebPartManager.DesignMode && _initializedSet && (value != InitialScope)) { 
                    throw new InvalidOperationException(
                        SR.GetString(SR.WebPartPersonalization_MustSetBeforeInit, "InitialScope", "WebPartPersonalization")); 
                }

                _initialScope = value;
            } 
        }
 
        ///  
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public bool IsEnabled { 
            get {
                return IsInitialized; 
            } 
        }
 
        /// 
        /// Indicates whether personalization state has been loaded. Properties of this
        /// object cannot be saved once this object is initialized.
        ///  
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        protected bool IsInitialized { 
            get {
                return _initialized;
            }
        } 

        ///  
        /// Determines if personalization and the ability to modify personalization state is enabled 
        /// in the current request. This depends on whether a user is authenticated for this request,
        /// and if that user has the rights to modify personalization state. 
        /// To check if just personalization is enabled at all, the IsEnabled property
        /// should be used.
        /// 
        [ 
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ] 
        public bool IsModifiable {
            get { 
                // We cannot cache this value, since UserCapabilities is protected virtual,
                // and could return a different value at any time
                IDictionary userCapabilities = UserCapabilities;
                bool isModifiable = (userCapabilities != null) && 
                    (userCapabilities.Contains(WebPartPersonalization.ModifyStateUserCapability));
                return isModifiable; 
            } 
        }
 
        /// 
        /// 
        [
        DefaultValue(""), 
        NotifyParentProperty(true),
        WebSysDescription(SR.WebPartPersonalization_ProviderName) 
        ] 
        public virtual string ProviderName {
            get { 
                return (_providerName != null) ? _providerName : String.Empty;
            }
            set {
                if (!WebPartManager.DesignMode && _initializedSet && 
                    !String.Equals(value, ProviderName, StringComparison.Ordinal)) {
                    throw new InvalidOperationException( 
                        SR.GetString(SR.WebPartPersonalization_MustSetBeforeInit, "ProviderName", "WebPartPersonalization")); 
                }
 
                _providerName = value;
            }
        }
 
        [
        Browsable(false), 
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ]
        public PersonalizationScope Scope { 
            get {
                return _currentScope;
            }
        } 

        internal bool ScopeToggled { 
            get { 
                return _scopeToggled;
            } 
        }

        // True if the personalization data was reset this request.  If so, we will not save data
        // at the end of the request. 
        protected bool ShouldResetPersonalizationState {
            get { 
                return _shouldResetPersonalizationState; 
            }
            set { 
                _shouldResetPersonalizationState = value;
            }
        }
 
        protected virtual IDictionary UserCapabilities {
            get { 
                if (_userCapabilities == null) { 
                    _userCapabilities = new HybridDictionary();
                } 
                return _userCapabilities;
            }
        }
 
        protected WebPartManager WebPartManager {
            get { 
                return _owner; 
            }
        } 

        /// 
        /// 
        protected internal virtual void ApplyPersonalizationState() { 
            if (IsEnabled) {
                EnsurePersonalizationState(); 
                _personalizationState.ApplyWebPartManagerPersonalization(); 
            }
        } 

        /// 
        /// 
        protected internal virtual void ApplyPersonalizationState(WebPart webPart) { 
            if (webPart == null) {
                throw new ArgumentNullException("webPart"); 
            } 

            if (IsEnabled) { 
                EnsurePersonalizationState();
                _personalizationState.ApplyWebPartPersonalization(webPart);
            }
        } 

        // Helper method used by CopyPersonalizationState() 
        private void ApplyPersonalizationState(Control control, PersonalizationInfo info) { 
            ITrackingPersonalizable trackingPersonalizable = control as ITrackingPersonalizable;
            IPersonalizable customPersonalizable = control as IPersonalizable; 

            if (trackingPersonalizable != null) {
                trackingPersonalizable.BeginLoad();
            } 

            // If customPersonalizable is null, then info.CustomProperties should also be null 
            Debug.Assert(!(customPersonalizable == null && info.CustomProperties != null)); 

            if (customPersonalizable != null && info.CustomProperties != null && info.CustomProperties.Count > 0) { 
                customPersonalizable.Load(info.CustomProperties);
            }

            if (info.Properties != null && info.Properties.Count > 0) { 
                BlobPersonalizationState.SetPersonalizedProperties(control, info.Properties);
            } 
 
            if (trackingPersonalizable != null) {
                trackingPersonalizable.EndLoad(); 
            }
        }

        protected virtual void ChangeScope(PersonalizationScope scope) { 
            PersonalizationProviderHelper.CheckPersonalizationScope(scope);
 
            if (scope == _currentScope) { 
                return;
            } 

            if ((scope == PersonalizationScope.Shared) && (!CanEnterSharedScope)) {
                throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CannotEnterSharedScope));
            } 

            _currentScope = scope; 
            _scopeToggled = true; 
        }
 
        // Extracts the personalization state from webPartA, and applies it to webPartB.
        // Assumes that webPartA and webPartB are the same type.  If the WebParts are GenericWebParts,
        // then copies the personalization state from the ChildControl of webPartA to the
        // ChildControl of webPartB. 
        protected internal virtual void CopyPersonalizationState(WebPart webPartA, WebPart webPartB) {
            if (webPartA == null) { 
                throw new ArgumentNullException("webPartA"); 
            }
            if (webPartB == null) { 
                throw new ArgumentNullException("webPartB");
            }
            if (webPartA.GetType() != webPartB.GetType()) {
                throw new ArgumentException(SR.GetString( 
                    SR.WebPartPersonalization_SameType, "webPartA", "webPartB"));
            } 
 
            CopyPersonalizationState((Control)webPartA, (Control)webPartB);
 
            GenericWebPart genericWebPartA = webPartA as GenericWebPart;
            GenericWebPart genericWebPartB = webPartB as GenericWebPart;
            // Assert that the GenericWebParts are either both null or both non-null
            Debug.Assert((genericWebPartA == null) == (genericWebPartB == null)); 
            if (genericWebPartA != null && genericWebPartB != null) {
                Control childControlA = genericWebPartA.ChildControl; 
                Control childControlB = genericWebPartB.ChildControl; 

                if (childControlA == null) { 
                    throw new ArgumentException(SR.GetString(
                        SR.PropertyCannotBeNull, "ChildControl"), "webPartA");
                }
                if (childControlB == null) { 
                    throw new ArgumentException(SR.GetString(
                        SR.PropertyCannotBeNull, "ChildControl"), "webPartB"); 
                } 
                if (childControlA.GetType() != childControlB.GetType()) {
                    throw new ArgumentException(SR.GetString( 
                        SR.WebPartPersonalization_SameType, "webPartA.ChildControl", "webPartB.ChildControl"));
                }

                CopyPersonalizationState(childControlA, childControlB); 
            }
 
            // IPersonalizable.IsDirty should always be false on the new WebPart, since the only data 
            // on the new WebPart was loaded via personalization, which should not cause the control
            // to be dirty.  However, we want to save the IPersonalizable data on this request, so 
            // we call SetDirty() to force the IPersonalizable data to be saved.
            SetDirty(webPartB);
        }
 
        private void CopyPersonalizationState(Control controlA, Control controlB) {
            PersonalizationInfo info = ExtractPersonalizationState(controlA); 
            ApplyPersonalizationState(controlB, info); 
        }
 
        /// 
        /// 
        private void DeterminePersonalizationProvider() {
            string providerName = ProviderName; 
            if (String.IsNullOrEmpty(providerName)) {
                // Use the default provider 
                _provider = PersonalizationAdministration.Provider; 
                // The default provider can never be null
                Debug.Assert(_provider != null); 
            }
            else {
                // Look for a provider with the specified name
                PersonalizationProvider provider = PersonalizationAdministration.Providers[providerName]; 
                if (provider != null) {
                    _provider = provider; 
                } 
                else {
                    throw new ProviderException( 
                        SR.GetString(SR.WebPartPersonalization_ProviderNotFound, providerName));
                }
            }
        } 

        ///  
        ///  
        public void EnsureEnabled(bool ensureModifiable) {
            bool value = (ensureModifiable ? IsModifiable : IsEnabled); 

            if (!value) {
                string message;
                if (ensureModifiable) { 
                    message = SR.GetString(SR.WebPartPersonalization_PersonalizationNotModifiable);
                } 
                else { 
                    message = SR.GetString(SR.WebPartPersonalization_PersonalizationNotEnabled);
                } 
                throw new InvalidOperationException(message);
            }
        }
 
        private void EnsurePersonalizationState() {
            if (_personalizationState == null) { 
                throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_PersonalizationStateNotLoaded)); 
            }
        } 

        /// 
        /// 
        protected internal virtual void ExtractPersonalizationState() { 
            // If we reset the personalization data on this request, we should not extract data since
            // it will not be saved. 
            if (IsEnabled && !ShouldResetPersonalizationState) { 
                EnsurePersonalizationState();
                _personalizationState.ExtractWebPartManagerPersonalization(); 
            }
        }

        ///  
        /// 
        protected internal virtual void ExtractPersonalizationState(WebPart webPart) { 
            // If we reset the personalization data on this request, we should not extract data since 
            // it will not be saved.
            if (IsEnabled && !ShouldResetPersonalizationState) { 
                EnsurePersonalizationState();
                _personalizationState.ExtractWebPartPersonalization(webPart);
            }
        } 

        // Helper method used by CopyPersonalizationState() 
        private PersonalizationInfo ExtractPersonalizationState(Control control) { 
            ITrackingPersonalizable trackingPersonalizable = control as ITrackingPersonalizable;
            IPersonalizable customPersonalizable = control as IPersonalizable; 

            if (trackingPersonalizable != null) {
                trackingPersonalizable.BeginSave();
            } 

            PersonalizationInfo info = new PersonalizationInfo(); 
            if (customPersonalizable != null) { 
                info.CustomProperties = new PersonalizationDictionary();
                customPersonalizable.Save(info.CustomProperties); 
            }
            info.Properties = BlobPersonalizationState.GetPersonalizedProperties(control, PersonalizationScope.Shared);

            if (trackingPersonalizable != null) { 
                trackingPersonalizable.EndSave();
            } 
 
            return info;
        } 

        // Returns the AuthorizationFilter string for a WebPart before it is instantiated
        // Returns null if there is no personalized value for AuthorizationFilter
        protected internal virtual string GetAuthorizationFilter(string webPartID) { 
            if (String.IsNullOrEmpty(webPartID)) {
                throw ExceptionUtil.ParameterNullOrEmpty("webPartID"); 
            } 

            EnsureEnabled(false); 
            EnsurePersonalizationState();
            return _personalizationState.GetAuthorizationFilter(webPartID);
        }
 
        /// 
        ///  
        internal void LoadInternal() { 
            if (Enabled) {
                _currentScope = Load(); 
                _initialized = true;
            }
            _initializedSet = true;
        } 

        ///  
        /// Loads personalization information from its storage, and computes the initial personalization 
        /// scope. This method determines the provider type to be used, and the current user's capabilities.
        ///  
        protected virtual PersonalizationScope Load() {
            if (!Enabled) {
                throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_PersonalizationNotEnabled));
            } 

            // Determine the provider early, as it is needed to continue execution. 
            // Provider is used to detect user's capabilities, load personalization state 
            // and determine initial scope.
            DeterminePersonalizationProvider(); 
            Debug.Assert(_provider != null);

            Page page = WebPartManager.Page;
            if (page == null) { 
                throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
            } 
 
            HttpRequest request = page.RequestInternal;
            if (request == null) { 
                throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page.Request"));
            }

            // Ask the provider to load information about what are the capabilities of 
            // the current user
            if (request.IsAuthenticated) { 
                _userCapabilities = _provider.DetermineUserCapabilities(WebPartManager); 
            }
 
            // A derived WebPartPersonalization can have ignoreCurrentUser to be true.
            _personalizationState = _provider.LoadPersonalizationState(WebPartManager, /* ignoreCurrentUser */ false);
            if (_personalizationState == null) {
                // We can't assume that _personalizationState will be non-null, because 
                // it depends on the provider implementation.
                throw new ProviderException(SR.GetString(SR.WebPartPersonalization_CannotLoadPersonalization)); 
            } 

            return _provider.DetermineInitialScope(WebPartManager, _personalizationState); 
        }

        // Resets the personalization data for the current user in the current scope on the current page
        public virtual void ResetPersonalizationState() { 
            EnsureEnabled(/* ensureModifiable */ true);
 
            if (_provider == null) { 
                throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CantCallMethodBeforeInit,
                                                    "ResetPersonalizationState", "WebPartPersonalization")); 
            }

            _provider.ResetPersonalizationState(WebPartManager);
            ShouldResetPersonalizationState = true; 

            Page page = WebPartManager.Page; 
            if (page == null) { 
                throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
            } 

            // Transfer execution to a new instance of the same page.  The new page will execute
            // after personalization data has been reset.
            TransferToCurrentPage(page); 
        }
 
        ///  
        /// 
        internal void SaveInternal() { 
            if (IsModifiable) {
                Save();
            }
        } 

        ///  
        /// Saves personalization information back to its storage if necessary. 
        /// 
        protected virtual void Save() { 
            EnsureEnabled(/* ensureModifiable */ true);

            EnsurePersonalizationState();
 
            if (_provider == null) {
                throw new InvalidOperationException(SR.GetString(SR.WebPartPersonalization_CantCallMethodBeforeInit, 
                                                    "Save", "WebPartPersonalization")); 
            }
 
            // If we reset the personalization data on this request, we should not save data to the
            // DB on this request.  It is likely we would not save data anyway, since the data probably
            // did not change since the last request, but there are some scenarios where the data could
            // have changed (like a WebPart using personalization as a cache). 
            if (_personalizationState.IsDirty && !ShouldResetPersonalizationState) {
                _provider.SavePersonalizationState(_personalizationState); 
            } 
        }
 
        /// 
        /// 
        protected internal virtual void SetDirty() {
            if (IsEnabled) { 
                EnsurePersonalizationState();
                _personalizationState.SetWebPartManagerDirty(); 
            } 
        }
 
        /// 
        /// 
        protected internal virtual void SetDirty(WebPart webPart) {
            if (IsEnabled) { 
                EnsurePersonalizationState();
                _personalizationState.SetWebPartDirty(webPart); 
            } 
        }
 
        /// 
        /// 
        public virtual void ToggleScope() {
            EnsureEnabled(/* ensureModifiable */ false); 

            Page page = WebPartManager.Page; 
            if (page == null) { 
                throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page"));
            } 
            if (page.IsExportingWebPart) {
                // If the page is exporting, the page determines the desired scope, and it is not meaningful
                // to toggle the scope. Note that we no-op the call, rather than throwing because
                // that would require exposing a CanToggleScope property, require page developers 
                // to check for it. Furthermore, we don't guarantee ToggleScope does toggle
                // (eg. in the case of absense of user capability to enter shared scope), so 
                // simply no-op'ing isn't terribly bad... 
                return;
            } 

            Page previousPage = page.PreviousPage;
            if ((previousPage != null) &&
                (previousPage.IsCrossPagePostBack == false)) { 
                WebPartManager previousWebPartManager = WebPartManager.GetCurrentWebPartManager(previousPage);
 
                if ((previousWebPartManager != null) && (previousWebPartManager.Personalization.ScopeToggled)) { 
                    // Looks like some sort of infinite recursion is going on
                    // and we're toggling again. Like the previous case, we're 
                    // going to no-op and protect ourselves from bad code...
                    return;
                }
            } 

            if (_currentScope == PersonalizationScope.Shared) { 
                ChangeScope(PersonalizationScope.User); 
            }
            else { 
                ChangeScope(PersonalizationScope.Shared);
            }

            // Transfer execution to a new instance of the same page.  The new page will detect the scope 
            // it should run in, when it begins to load personalization data.
            TransferToCurrentPage(page); 
        } 

        // Transfers execution to a new instance of the same page. We need to clear the form collection, 
        // since it should not carry over to the page in the new scope (i.e. ViewState). If the form
        // method is GET, then we must not include the query string, since the entire form collection
        // is in the query string.  If the form method is POST (or there is no form), then we must
        // include the query string, since the developer could be using the query string to drive the 
        // logic of their page (VSWhidbey 444385 and 527117).
        private void TransferToCurrentPage(Page page) { 
            HttpRequest request = page.RequestInternal; 
            if (request == null) {
                throw new InvalidOperationException(SR.GetString(SR.PropertyCannotBeNull, "WebPartManager.Page.Request")); 
            }

            string path = request.CurrentExecutionFilePath;
            if (page.Form == null || String.Equals(page.Form.Method, "post", StringComparison.OrdinalIgnoreCase)) { 
                string queryString = page.ClientQueryString;
                if (!String.IsNullOrEmpty(queryString)) { 
                    path += "?" + queryString; 
                }
            } 

            IScriptManager scriptManager = page.ScriptManager;
            if ((scriptManager != null) && scriptManager.IsInAsyncPostBack) {
                request.Response.Redirect(path); 
            }
            else { 
                page.Server.Transfer(path, /* preserveForm */ false); 
            }
        } 

        private sealed class PersonalizationInfo {
            public IDictionary Properties;
            public PersonalizationDictionary CustomProperties; 
        }
    } 
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK