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

📄 scriptobjectbuilder.cs

📁 AJAX 应用 实现页面的无刷新
💻 CS
📖 第 1 页 / 共 3 页
字号:
        /// <returns></returns>
        public static IEnumerable<ScriptReference> GetScriptReferences(Type type)
        {
            return GetScriptReferences(type, false);
        }

        /// <summary>
        /// Gets the ScriptReferences for a Type
        /// </summary>
        /// <param name="type">Type for which references are to be gotten</param>
        /// <param name="ignoreStartingTypeReferences">true if the ClientScriptResource for the starting type is to be ignored</param>
        /// <returns>list of ScriptReferences for the Type</returns>
        public static IEnumerable<ScriptReference> GetScriptReferences(Type type, bool ignoreStartingTypeReferences)
        {
            List<ResourceEntry> entries = GetScriptReferencesInternal(type, new Stack<Type>(), ignoreStartingTypeReferences);

            return ScriptReferencesFromResourceEntries(entries);
        }

        /// <summary>
        /// Gets the embedded css file references for a type
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IEnumerable<string> GetCssReferences(Control control)
        {
            return GetCssReferences(control, control.GetType(), new Stack<Type>());
        }

        /// <summary>
        /// Register's the Css references for this control
        /// </summary>
        /// <param name="control"></param>
        public static void RegisterCssReferences(Control control)
        {
            // Add the link to the page header instead of inside the body which is not xhtml compliant
            HtmlHead header = control.Page.Header;

            foreach (string styleSheet in ScriptObjectBuilder.GetCssReferences(control))
            {
                if (null == header)
                {
                    // It would be nice to add the required header here, but it's too late in the page
                    // lifecycle to be modifying the Page.Controls collection - throw an informative
                    // exception instead and let the page author make the simple change.
                    throw new NotSupportedException("This page is missing a HtmlHead control which is required for the CSS stylesheet link that is being added. Please add <head runat=\"server\" />.");
                }

                bool addIt = true;  // looking for this stylesheet already in the header
                foreach (Control c in header.Controls)
                {
                    HtmlLink l = c as HtmlLink;
                    if (null != l && styleSheet.Equals(l.Href, StringComparison.OrdinalIgnoreCase))
                    {
                        addIt = false;
                        break;
                    }
                }

                if (addIt)
                {
                    HtmlLink link = new HtmlLink();
                    link.Href = styleSheet;
                    link.Attributes.Add("type", "text/css");
                    link.Attributes.Add("rel", "stylesheet");
                    header.Controls.Add(link);

                    // ASP.NET AJAX doesn't currently send a new head element down during an async postback,
                    // so we do the same thing on the client by registering the appropriate script for after
                    // the update. A HiddenField is used to prevent multiple registrations.
                    ScriptManager scriptManager = ScriptManager.GetCurrent(control.Page);
                    if (null == scriptManager)
                    {
                        throw new InvalidOperationException(Resources.E_NoScriptManager);
                    }
                    if (scriptManager.IsInAsyncPostBack &&
                        (null == control.Page.Request.Form["__AjaxControlToolkitCalendarCssLoaded"]))
                    {
                        ScriptManager.RegisterClientScriptBlock(control, control.GetType(), "RegisterCssReferences",
                            "var head = document.getElementsByTagName('HEAD')[0];" +
                            "if (head) {" +
                                "var linkElement = document.createElement('link');" +
                                "linkElement.type = 'text/css';" +
                                "linkElement.rel = 'stylesheet';" +
                                "linkElement.href = '" + styleSheet + "';" +
                                "head.appendChild(linkElement);" +
                            "}"
                            , true);
                        ScriptManager.RegisterHiddenField(control, "__AjaxControlToolkitCalendarCssLoaded", "");
                    }
                }
            }
        }

        /// <summary>
        /// Executes a callback capable method on a control
        /// </summary>
        /// <param name="control"></param>
        /// <param name="callbackArgument"></param>
        /// <returns></returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification="Deliberate attempt to catch and pass-on all exceptions")]
        public static string ExecuteCallbackMethod(Control control, string callbackArgument)
        {
            Type controlType = control.GetType();

            // Deserialize the callback JSON into CLR objects
            JavaScriptSerializer js = new JavaScriptSerializer();
            Dictionary<string, object> callInfo = js.DeserializeObject(callbackArgument) as Dictionary<string, object>;

            // Get the call information
            string methodName = (string)callInfo["name"];
            object[] args = (object[])callInfo["args"];
            string clientState = (string)callInfo["state"];

            // Attempt to load the client state
            IClientStateManager csm = control as IClientStateManager;
            if (csm != null && csm.SupportsClientState)
            {
                csm.LoadClientState(clientState);
            }

            // call the method
            object result = null;
            string error = null;
            try
            {
                // Find a matching static or instance method.  Only public methods can be invoked
                MethodInfo mi = controlType.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
                if (mi == null)
                {
                    throw new MissingMethodException(controlType.FullName, methodName);
                }
                
                // Verify that the method has the corrent number of parameters as well as the ExtenderControlMethodAttribute
                ParameterInfo[] methodParams = mi.GetParameters();
                ExtenderControlMethodAttribute methAttr = (ExtenderControlMethodAttribute)Attribute.GetCustomAttribute(mi, typeof(ExtenderControlMethodAttribute));
                if (methAttr == null || !methAttr.IsScriptMethod || args.Length != methodParams.Length)
                {
                    throw new MissingMethodException(controlType.FullName, methodName);
                }

                // Convert each argument to the parameter type if possible
                // NOTE: I'd rather have the ObjectConverter from within System.Web.Script.Serialization namespace for this
                object[] targetArgs = new object[args.Length];
                for (int i = 0; i < targetArgs.Length; i++)
                {
                    if (args[i] == null)
                        continue;
                    targetArgs[i] = Convert.ChangeType(args[i], methodParams[i].ParameterType, CultureInfo.InvariantCulture);
                }
                result = mi.Invoke(control, targetArgs);
            }
            catch (Exception ex)
            {
                // Catch the exception information to relay back to the client
                if (ex is TargetInvocationException)
                {
                    ex = ex.InnerException;
                }
                error = ex.GetType().FullName + ":" + ex.Message;
            }

            // return the result
            Dictionary<string, object> resultInfo = new Dictionary<string, object>();
            if (error == null)
            {
                resultInfo["result"] = result;
                if (csm != null && csm.SupportsClientState)
                {
                    resultInfo["state"] = csm.SaveClientState();
                }
            }
            else
            {
                resultInfo["error"] = error;
            }

            // Serialize the result info into JSON
            return js.Serialize(resultInfo);
        }

        /// <summary>
        /// ScriptReference objects aren't immutable.  The AJAX core adds context to them, so we cant' reuse them.
        /// Therefore, we track only ReferenceEntries internally and then convert them to NEW ScriptReference objects on-demand.        
        /// </summary>
        /// <param name="entries"></param>
        /// <returns></returns>
        private static IEnumerable<ScriptReference> ScriptReferencesFromResourceEntries(IList<ResourceEntry> entries)
        {
            IList<ScriptReference> referenceList = new List<ScriptReference>(entries.Count);
            
            foreach (ResourceEntry re in entries)
            {
                referenceList.Add(re.ToScriptReference());
            }
            return referenceList;
        }

        /// <summary>
        /// Gets the ScriptReferences for a Type and walks the Type's dependencies with circular-reference checking
        /// </summary>
        /// <param name="type">Type for which references are to be gotten</param>
        /// <param name="typeReferenceStack">Stack of Types to track processed types</param>
        /// <param name="ignoreStartingTypeReferences">true if the ClientScriptResource for the starting type is to be ignored</param>
        /// <returns>list of ScriptReferences for the Type</returns>
        private static List<ResourceEntry> GetScriptReferencesInternal(Type type, Stack<Type> typeReferenceStack, bool ignoreStartingTypeReferences)
        {
            // Verify no circular references
            if (typeReferenceStack.Contains(type))
            {
                throw new InvalidOperationException("Circular reference detected.");
            }

            // Look for a cached set of references outside of the lock for perf.
            //
            List<ResourceEntry> entries;

            // Don't check the cache for "unusual" responses
            if (!ignoreStartingTypeReferences && _cache.TryGetValue(type, out entries))
            {
                return entries;
            }

            // Track this type to prevent circular references
            typeReferenceStack.Push(type);
            try
            {
                lock (_sync)
                {

⌨️ 快捷键说明

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