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

📄 toolkitscriptmanager.cs

📁 AJAX 应用 实现页面的无刷新
💻 CS
📖 第 1 页 / 共 3 页
字号:
                using (StreamWriter outputWriter = new StreamWriter(outputStream))
                {
                    // Get the list of scripts to combine
                    List<ScriptEntry> scriptEntries = DeserializeScriptEntries(HttpUtility.UrlDecode(combinedScripts), false);

                    // Write the scripts
                    WriteScripts(scriptEntries, outputWriter);

                    // Write the ASP.NET AJAX script notification code
                    outputWriter.WriteLine("if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();");

                    // Write a handler to run on page load and update the hidden field tracking scripts loaded in the browser
                    outputWriter.WriteLine(string.Format(CultureInfo.InvariantCulture, 
                        "(function() {{" +
                            "var fn = function() {{" +
                                "$get('{0}').value += '{1}';" +
                                "Sys.Application.remove_load(fn);" +
                            "}};" +
                            "Sys.Application.add_load(fn);" +
                        "}})();", hiddenFieldName, SerializeScriptEntries(scriptEntries, true)));
                }

                output = true;
            }
            return output;
        }

        /// <summary>
        /// Writes scripts (including localized script resources) to the specified stream
        /// </summary>
        /// <param name="scriptEntries">list of scripts to write</param>
        /// <param name="outputWriter">writer for output stream</param>
        private static void WriteScripts(List<ScriptEntry> scriptEntries, TextWriter outputWriter)
        {
            foreach (ScriptEntry scriptEntry in scriptEntries)
            {
                if (!scriptEntry.Loaded)
                {
                    if (!IsScriptCombinable(scriptEntry))
                    {
                        throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Combined script request includes uncombinable script \"{0}\".", scriptEntry.Name));
                    }

                    // This script hasn't been loaded by the browser, so add it to the combined script file
                    outputWriter.Write("//START ");
                    outputWriter.WriteLine(scriptEntry.Name);
                    string script = scriptEntry.GetScript();
                    if (WebResourceRegex.IsMatch(script))
                    {
                        // This script uses script substitution which isn't supported yet, so throw an exception since it's too late to fix
                        throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "ToolkitScriptManager does not support <%= WebResource/ScriptResource(...) %> substitution as used by script file \"{0}\".", scriptEntry.Name));
                    }
                    outputWriter.WriteLine(script);

                    // Save current culture and set the specified culture
                    CultureInfo currentUiCulture = Thread.CurrentThread.CurrentUICulture;
                    try
                    {
                        try
                        {
                            Thread.CurrentThread.CurrentUICulture = new CultureInfo(scriptEntry.Culture);
                        }
                        catch (ArgumentException)
                        {
                            // Invalid culture; proceed with default culture (just as for unsupported cultures)
                        }

                        // Write out the associated script resources (if any) in the proper culture
                        Assembly scriptAssembly = scriptEntry.LoadAssembly();
                        foreach (ScriptResourceAttribute scriptResourceAttribute in scriptAssembly.GetCustomAttributes(typeof(ScriptResourceAttribute), false))
                        {
                            if (scriptResourceAttribute.ScriptName == scriptEntry.Name)
                            {
                                // Found a matching script resource; write it out
                                outputWriter.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0}={{", scriptResourceAttribute.TypeName));

                                // Get the script resource name (without the trailing ".resources")
                                string scriptResourceName = scriptResourceAttribute.ScriptResourceName;
                                if (scriptResourceName.EndsWith(".resources", StringComparison.OrdinalIgnoreCase))
                                {
                                    scriptResourceName = scriptResourceName.Substring(0, scriptResourceName.Length - 10);
                                }

                                // Load a ResourceManager/ResourceSet and walk through the list to output them all
                                System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(scriptResourceName, scriptAssembly);
                                using (System.Resources.ResourceSet resourceSet = resourceManager.GetResourceSet(CultureInfo.InvariantCulture, true, true))
                                {
                                    bool first = true;
                                    foreach (System.Collections.DictionaryEntry de in resourceSet)
                                    {
                                        if (!first)
                                        {
                                            // Need a comma between all entries
                                            outputWriter.Write(",");
                                        }
                                        // Output the entry
                                        string name = (string)de.Key;
                                        string value = resourceManager.GetString(name);
                                        outputWriter.Write(string.Format(CultureInfo.InvariantCulture, "\"{0}\":\"{1}\"", QuoteString(name), QuoteString(value)));
                                        first = false;
                                    }
                                }
                                outputWriter.WriteLine("};");
                            }
                        }

                    }
                    finally
                    {
                        // Restore culture
                        Thread.CurrentThread.CurrentUICulture = currentUiCulture;
                    }

                    // Done with this script
                    outputWriter.Write("//END ");
                    outputWriter.WriteLine(scriptEntry.Name);
                }

                // This script is now (or will be soon) loaded by the browser
                scriptEntry.Loaded = true;
            }
        }

        /// <summary>
        /// Checks if the specified ScriptEntry is combinable
        /// </summary>
        /// <param name="scriptEntry">ScriptEntry to check</param>
        /// <returns>true iff combinable</returns>
        private static bool IsScriptCombinable(ScriptEntry scriptEntry)
        {
            // Load the script's assembly and look for ScriptCombineAttribute
            bool combinable = false;
            Assembly assembly = scriptEntry.LoadAssembly();
            foreach (ScriptCombineAttribute scriptCombineAttribute in assembly.GetCustomAttributes(typeof(ScriptCombineAttribute), false))
            {
                if (string.IsNullOrEmpty(scriptCombineAttribute.IncludeScripts))
                {
                    // If the IncludeScripts property is empty, all scripts are combinable by default
                    combinable = true;
                }
                else
                {
                    // IncludeScripts specifies the combinable scripts
                    foreach (string includeScript in scriptCombineAttribute.IncludeScripts.Split(','))
                    {
                        // If this script name matches, it's combinable
                        if (0 == string.Compare(scriptEntry.Name, includeScript.Trim(), StringComparison.OrdinalIgnoreCase))
                        {
                            combinable = true;
                            break;
                        }
                    }
                }
                if (!string.IsNullOrEmpty(scriptCombineAttribute.ExcludeScripts))
                {
                    // ExcludeScripts specifies the non-combinable scripts (and overrides IncludeScripts)
                    foreach (string excludeScript in scriptCombineAttribute.ExcludeScripts.Split(','))
                    {
                        // If the script name matches, it's not combinable
                        if (0 == string.Compare(scriptEntry.Name, excludeScript.Trim(), StringComparison.OrdinalIgnoreCase))
                        {
                            combinable = false;
                            break;
                        }
                    }
                }
            }
            if (combinable)
            {
                // Make sure the script has an associated WebResourceAttribute (else ScriptManager wouldn't have served it)
                bool correspondingWebResourceAttribute = false;
                foreach (WebResourceAttribute webResourceAttribute in assembly.GetCustomAttributes(typeof(WebResourceAttribute), false))
                {
                    if (scriptEntry.Name == webResourceAttribute.WebResource)
                    {
                        correspondingWebResourceAttribute = true;
                        break;
                    }
                }
                // Don't allow it to be combined if not
                combinable &= correspondingWebResourceAttribute;
            }
            return combinable;
        }

        /// <summary>
        /// Serialize a list of ScriptEntries
        /// </summary>
        /// <remarks>
        /// Serialized list looks like:
        /// ;Assembly1.dll Version=1:Culture:MVID1:ScriptName1Hash:ScriptName2Hash;Assembly2.dll Version=2:Culture:MVID1:ScriptName3Hash
        /// </remarks>
        /// <param name="scriptEntries">list of scripts to serialize</param>
        /// <param name="allScripts">true iff all scripts should be serialized; otherwise only not loaded ones</param>
        /// <returns>serialized list</returns>
        private static string SerializeScriptEntries(List<ScriptEntry> scriptEntries, bool allScripts)
        {
            // Serialized string must never be null (';' is safe)
            StringBuilder serializedScriptEntries = new StringBuilder(";");
            string currentAssembly = null;
            foreach (ScriptEntry scriptEntry in scriptEntries)
            {
                if (allScripts || !scriptEntry.Loaded)
                {
                    // Serializing this script name
                    if (currentAssembly != scriptEntry.Assembly)
                    {
                        // It's a different assembly, so serialize the assembly name and Culture.MVID value first
                        serializedScriptEntries.Append(";");
                        serializedScriptEntries.Append(scriptEntry.Assembly);
                        serializedScriptEntries.Append(":");
                        serializedScriptEntries.Append(CultureInfo.CurrentUICulture.IetfLanguageTag);
                        serializedScriptEntries.Append(":");
                        serializedScriptEntries.Append(scriptEntry.LoadAssembly().ManifestModule.ModuleVersionId);
                        currentAssembly = scriptEntry.Assembly;
                    }
                    // Serialize the script name hash
                    serializedScriptEntries.Append(":");
                    serializedScriptEntries.Append(scriptEntry.Name.GetHashCode().ToString("x", CultureInfo.InvariantCulture));
                }
            }
            return serializedScriptEntries.ToString();
        }

        /// <summary>
        /// Deserialize a list of ScriptEntries
        /// </summary>
        /// <remarks>
        /// Serialized list looks like:
        /// ;Assembly1.dll Version=1:Culture:MVID1:ScriptName1Hash:ScriptName2Hash;Assembly2.dll Version=2:Culture:MVID1:ScriptName3Hash
        /// </remarks>
        /// <param name="serializedScriptEntries">serialized list</param>
        /// <param name="loaded">loaded state of the serialized scripts</param>
        /// <returns>list of scripts</returns>
        private static List<ScriptEntry> DeserializeScriptEntries(string serializedScriptEntries, bool loaded)
        {
            List<ScriptEntry> scriptEntries = new List<ScriptEntry>();
            foreach (string assemblyScripts in serializedScriptEntries.Split(';'))
            {
                // Deserialize this assembly's scripts
                string assembly = null;
                string culture = null;
                string mvid = null;
                Dictionary<string, string> resourceNameHashToResourceName = null;
                foreach (string script in assemblyScripts.Split(':'))
                {
                    if (null == assembly)
                    {
                        // Haven't got the assembly name yet; this is it
                        assembly = script;
                    }
                    else if (null == culture)
                    {
                        // Haven't got the culture value yet; this is it
                        culture = script;
                    }
                    else if (null == mvid)
                    {
                        // Haven't got the MVID value yet; this is it

⌨️ 快捷键说明

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