⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sqlstateclientmanager.cs

📁 MasterPage(母版页) 母版页(MasterPage)就相当于模板页
💻 CS
📖 第 1 页 / 共 5 页
字号:
//------------------------------------------------------------------------------
// <copyright file="SqlSessionStateStore.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
//------------------------------------------------------------------------------

/*
 * SqlSessionStateStore.cs
 * 
 * Copyright (c) 1998-2000, Microsoft Corporation
 * 
 */
 
namespace Microsoft.Samples {

    using System;
    using System.Configuration;
    using System.Collections;
    using System.Threading;
    using System.IO;
    using System.Web;
    using System.Web.Caching;
    using System.Web.Util;
    using System.Data;
    using System.Data.SqlClient;
    using System.Data.Common;
    using System.Text;
    using System.Security.Principal;
    using System.Xml;
    using System.Collections.Specialized; 
    using System.Configuration.Provider;
    using System.Globalization;
    using System.Web.Management;
    using System.Web.Hosting;
    using System.Web.Configuration;
    using System.Web.SessionState;

    /*
     * Provides session state via SQL Server
     */
    public class SqlSessionStateStore : SessionStateStoreProviderBase {
    
        internal enum SupportFlags : uint {
            None =              0x00000000,
            GetLockAge =        0x00000001,
            Uninitialized =     0xFFFFFFFF
        }
        
        #pragma warning disable 0649
//        static ReadWriteSpinLock    s_lock;
        #pragma warning restore 0649
        static int          s_commandTimeout;
        static bool         s_oneTimeInited;
        static bool         s_usePartition = false;
        static EventHandler s_onAppDomainUnload;


        // We keep these info because we don't want to hold on to the config object.
        static string       s_configPartitionResolverType = null;
        static string       s_configSqlConnectionFileName;
        static int          s_configSqlConnectionLineNumber;
        static bool         s_configAllowCustomSqlDatabase;
        static string       s_sqlConnectionString;
        static SqlPartitionInfo s_singlePartitionInfo;
        
        // Per request info        
        HttpContext         _rqContext;
        int                 _rqOrigStreamLen;
        //IPartitionResolver  _partitionResolver = null;
        SqlPartitionInfo _partitionInfo;

        const int ITEM_SHORT_LENGTH =   7000;
        const int SQL_ERROR_PRIMARY_KEY_VIOLATION = 2627;
        const int SQL_LOGIN_FAILED = 18456;
        const int SQL_LOGIN_FAILED_2 = 18452;
        const int SQL_LOGIN_FAILED_3 = 18450;
        const int APP_SUFFIX_LENGTH = 8;
        
        static int ID_LENGTH = SessionIDManager.SessionIDMaxLength + APP_SUFFIX_LENGTH;
        internal const int SQL_COMMAND_TIMEOUT_DEFAULT = 30;        // in sec

        public SqlSessionStateStore() {
        }

        /*
        internal override void Initialize(string name, NameValueCollection config, IPartitionResolver partitionResolver) {
            _partitionResolver = partitionResolver;
            Initialize(name, config);
        }
         */

#if DBG
        SessionStateModule  _module;

        internal void SetModule(SessionStateModule module) {
            _module = module;
        }
#endif

        public override void Initialize(string name, NameValueCollection config)
        {
            if (String.IsNullOrEmpty(name))
                name = "SQL Server Session State Provider";

            base.Initialize(name, config);

            if (!s_oneTimeInited) {
//                s_lock.AcquireWriterLock();
                try {
                    if (!s_oneTimeInited) {
                        OneTimeInit();
                    }
                }
                finally {
//                    s_lock.ReleaseWriterLock();
                }
            }

            _partitionInfo = s_singlePartitionInfo;
        }

        void OneTimeInit() {
            SessionStateSection config = (SessionStateSection)WebConfigurationManager.GetSection("system.web/sessionState");

            s_configSqlConnectionFileName = config.ElementInformation.Properties["sqlConnectionString"].Source;
            s_configSqlConnectionLineNumber = config.ElementInformation.Properties["sqlConnectionString"].LineNumber;
            s_configAllowCustomSqlDatabase = config.AllowCustomSqlDatabase;

            s_sqlConnectionString = config.SqlConnectionString;
            if (String.IsNullOrEmpty(s_sqlConnectionString)) throw new Exception("No connection string specified");
            s_singlePartitionInfo = CreatePartitionInfo(s_sqlConnectionString);
            
            s_commandTimeout = (int)config.SqlCommandTimeout.TotalSeconds;

            // We only need to do this in one instance
            s_onAppDomainUnload = new EventHandler(OnAppDomainUnload);
            Thread.GetDomain().DomainUnload += s_onAppDomainUnload;

            // Last thing to set.
            s_oneTimeInited = true;
        }

        void OnAppDomainUnload(Object unusedObject, EventArgs unusedEventArgs) {
            //Debug.Trace("SqlSessionStateStore", "OnAppDomainUnload called");
            
            Thread.GetDomain().DomainUnload -= s_onAppDomainUnload;
        }

        internal SqlPartitionInfo CreatePartitionInfo(string sqlConnectionString) {
            /*
             * Parse the connection string for errors. We want to ensure
             * that the user's connection string doesn't contain an
             * Initial Catalog entry, so we must first create a dummy connection.
             */
            SqlConnection   dummyConnection;
            string          attachDBFilename = null;
            
            try {
                dummyConnection = new SqlConnection(sqlConnectionString);
            }
            catch (Exception e) {
                throw new Exception(
                    SR.GetString(SR.Error_parsing_session_sqlConnectionString, e.Message),
                    e);
            }

            // Search for both Database and AttachDbFileName.  Don't append our
            // database name if either of them exists.
            string database = dummyConnection.Database;
            SqlConnectionStringBuilder  scsb = new SqlConnectionStringBuilder(sqlConnectionString);

            if (String.IsNullOrEmpty(database)) {
                database = scsb.AttachDBFilename;
                attachDBFilename = database;
            }
            
            if (!String.IsNullOrEmpty(database)) {
                if (!s_configAllowCustomSqlDatabase) {
                    throw new Exception(SR.GetString(SR.No_database_allowed_in_sqlConnectionString));
                }

                if (attachDBFilename != null) {
//                    HttpRuntime.CheckFilePermission(attachDBFilename, true);
                }
            }
            else {
                scsb.Add("Initial Catalog", "ASPState");
            }

            return new SqlPartitionInfo(new ResourcePool(new TimeSpan(0, 0, 5), int.MaxValue),
                                            scsb.IntegratedSecurity,
                                            scsb.ConnectionString);
            
        }

        public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback) {
            return false;
        }
        
        public override void Dispose() {
        }

        public override void InitializeRequest(HttpContext context) {
            ////Debug.Assert(context != null, "context != null");
            
            _rqContext = context;
            _rqOrigStreamLen = 0;
            
/*            if (s_usePartition) {
                // For multiple partition case, the connection info can change from request to request
                _partitionInfo = null;
            }
 * 
 * 
 */

        }

        public override void EndRequest(HttpContext context) {
            ////Debug.Assert(context != null, "context != null");
            _rqContext = null;
        }

        public bool KnowForSureNotUsingIntegratedSecurity {
            get {
                if (_partitionInfo == null) {
                    ////Debug.Assert(s_usePartition, "_partitionInfo can be null only if we're using paritioning and we haven't called GetConnection yet.");
                    // If we're using partitioning, we need the session id to figure out the connection
                    // string.  Without it, we can't know for sure.
                    return false;
                }
                else {
                    ////Debug.Assert(_partitionInfo != null);
                    return !_partitionInfo.UseIntegratedSecurity;
                }
            }
        }

        //
        // Regarding resource pool, we will turn it on if in <identity>:
        //  - User is not using integrated security
        //  - impersonation = "false"
        //  - impersonation = "true" and userName/password is NON-null
        //  - impersonation = "true" and IIS is using Anonymous
        //
        // Otherwise, the impersonated account will be dynamic and we have to turn
        // resource pooling off.
        //
        // Note:
        // In case 2. above, the user can specify different usernames in different 
        // web.config in different subdirs in the app.  In this case, we will just 
        // cache the connections in the resource pool based on the identity of the 
        // connection.  So in this specific scenario it is possible to have the 
        // resource pool filled with mixed identities.
        // 
        bool CanUsePooling() {
            bool    ret = false;

            if (KnowForSureNotUsingIntegratedSecurity) {
                //Debug.Trace("SessionStatePooling", "CanUsePooling: not using integrated security");
                ret = true;
            }
            else if (_rqContext == null) {
                // One way this can happen is we hit an error on page compilation,
                // and SessionStateModule.OnEndRequest is called
                //Debug.Trace("SessionStatePooling", "CanUsePooling: no context");
                ret = false;
            }
//            else if (!_rqContext.IsClientImpersonationConfigured) {
                //Debug.Trace("SessionStatePooling", "CanUsePooling: mode is None or Application");
                //ret = true;
//            }
//            else if (HttpRuntime.IsOnUNCShareInternal) {
                //Debug.Trace("SessionStatePooling", "CanUsePooling: mode is UNC");
//                ret = false;
//            }
            else {
/*                string logon = _rqContext.WorkerRequest.GetServerVariable("LOGON_USER");

                //Debug.Trace("SessionStatePooling", "LOGON_USER = '" + logon + "'; identity = '" + _rqContext.User.Identity.Name + "'; IsUNC = " + HttpRuntime.IsOnUNCShareInternal);

                if (String.IsNullOrEmpty(logon)) {
                    ret = true;
                }
                else {
                    ret = false;
                }
 */
            }

            //Debug.Trace("SessionStatePooling", "CanUsePooling returns " + ret);
            return ret;
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -