WebPartPersonalization.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / xsp / System / Web / UI / WebParts / WebPartPersonalization.cs / 1305376 / 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.Principal;
    using System.Web; 
    using System.Web.Configuration; 
    using System.Web.UI;
    using System.Web.Util; 
    using System.Web.Hosting;

    [TypeConverterAttribute(typeof(EmptyStringExpandableObjectConverter))]
    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 "----" 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