首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网络安全-> 安全在线
updatepanel和自定义控件中的客户端脚本_asp.net技巧
作者:网友供稿 点击:0
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 

Over the last few weeks since MS Ajax Beta rolled around I’ve been getting a number of reports of the wwHoverPanel control running into some problems when running in combination with MS Ajax. The controls themselves don’t interfere with MS AJAX directly, but if you’re sticking the controls inside of an AJAX UpdatePanel() there’s a problem as the script code that the controls spit out don’t get properly generated into the callback generated updates. With the script code missing the controls still work but exhibit some unexpected behaviors. For example a hover panel placed into an update panel will lose it’s positioning in many cases and instead of popping up at the current mouse cursor position will pop up at the border of the container control it lives in.

 

The problem is that Microosft decided in MS AJAX Beta to go with a completely separate script generation engine which is driven through the ScriptManager control. The MS Ajax ScriptManager mimics many of the ClientScript object’s methods, but provides them as static methods (thankfully! without that we’d be really screwed).

 

So methods like RegisterClientScriptBlock, ResgisterClientScriptResources – anything that deals with getting script code into the page have related static methods in ScriptManager. The ScriptManager methods pass in the Control as an additional first parameter but otherwise mimic the existing ClientScriptManager.

 

This new behavior puts existing controls into a bind though – if code uses ClientScriptManager then UpdatePanels will not be able to see the script code (if it needs updating in a callback). But at the same time the control developer can’t make the assumption that the MS Ajax ScriptManager actually exists.

 

The end result of all of this is that it’s not exactly straight forward to deal with this mismatch and what needs to happen is that a wrapper object needs to be created that can decide which control to use. The wrapper needs to deal with deciding whether MS Ajax is available in the application and if it is, using Reflection to access the ScriptManager to write out any script code.

 

I can’t take credit for this though: Eilon Lipton posted about this issue a while back and his code really was what I needed to get this off the ground, I just wrapped the thing up into a ClientScriptProxy object that I used on a handful of controls. I basically added a handful of the ClientScript methods that I use in my applications. Here’s the class:

 

[*** code updated: 12/12/2006 from comments *** ]

 

/// <summary>

/// This is a proxy object for the Page.ClientScript and MS Ajax ScriptManager

/// object that can operate when MS Ajax is not present. Because MS Ajax

/// may not be available accessing the methods directly is not possible

/// and we are required to indirectly reference client script methods through

/// this class.

///

/// This class should be invoked at the Controls start up and be used

/// to replace all calls Page.ClientScript. Scriptmanager calls are made

/// through Reflection

/// </summary>

public class ClientScriptProxy

{

    private static Type scriptManagerType = null;

 

    // *** Register proxied methods of ScriptManager

    private static MethodInfo RegisterClientScriptBlockMethod;

    private static MethodInfo RegisterStartupScriptMethod;

    private static MethodInfo RegisterClientScriptIncludeMethod;

    private static MethodInfo RegisterClientScriptResourceMethod;

    //private static MethodInfo RegisterPostBackControlMethod;

    //private static MethodInfo GetWebResourceUrlMethod;

   

    ClientScriptManager clientScript;

 

    /// <summary>

    /// Determines if MsAjax is available in this Web application

    /// </summary>

    public bool IsMsAjax

    {

        get

        {

            if (scriptManagerType == null)

               CheckForMsAjax();

 

            return _IsMsAjax;

        }

    }

    private static bool _IsMsAjax = false;

 

   

    public bool IsMsAjaxOnPage

    {

        get

        {

            return _IsMsAjaxOnPage;

        }

    }

    private bool _IsMsAjaxOnPage = false;

 

 

    /// <summary>

    /// Current instance of this class which should always be used to

    /// access this object. There are no public constructors to

    /// ensure the reference is used as a Singleton.

    /// </summary>

    public static ClientScriptProxy Current

    {

        get

        {

                return

                ( HttpContext.Current.Items["__ClientScriptProxy"] ??

                (HttpContext.Current.Items["__ClientScriptProxy"] =

                    new ClientScriptProxy(HttpContext.Current.Handler as Page)))

                as ClientScriptProxy;

        }

    }

 

 

    /// <summary>

    /// Base constructor. Pass in the page name so we can pick up

    /// the stock the

    /// </summary>

    /// <param name="CurrentPage"></param>

    protected ClientScriptProxy(Page CurrentPage)

    {

        this.clientScript = CurrentPage.ClientScript;

    }

 

    /// <summary>

    /// Checks to see if MS Ajax is registered with the current

    /// Web application.

    ///

    /// Note: Method is static so it can be directly accessed from

    /// anywhere

    /// </summary>

    /// <returns></returns>

    public static bool CheckForMsAjax()

    {

        scriptManagerType = Type.GetType("Microsoft.Web.UI.ScriptManager, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", false);

        if (scriptManagerType != null)

        {

            _IsMsAjax = true;

            return true;

        }

 

       _IsMsAjax = false;

       return false;

    }

 

    /// <summary>

    /// Registers a client script block in the page.

    /// </summary>

    /// <param name="control"></param>

    /// <param name="type"></param>

    /// <param name="key"></param>

    /// <param name="script"></param>

    /// <param name="addScriptTags"></param>

    public void RegisterClientScriptBlock(Control control, Type type, string key, string script, bool addScriptTags)

    {

        if (this.IsMsAjax)

        {

            if (RegisterClientScriptBlockMethod == null)

                RegisterClientScriptBlockMethod = scriptManagerType.GetMethod("RegisterClientScriptBlock");

 

            RegisterClientScriptBlockMethod.Invoke(null, new object[5] { control, type, key, script, addScriptTags });

        }

        else

            this.clientScript.RegisterClientScriptBlock(type, key, script, addScriptTags);

    }

 

    /// <summary>

    /// Registers a startup code snippet that gets placed at the bottom of the page

    /// </summary>

    /// <param name="control"></param>

    /// <param name="type"></param>

    /// <param name="key"></param>

    /// <param name="script"></param>

    /// <param name="addStartupTags"></param>

    public void RegisterStartupScript(Control control, Type type, string key, string script, bool addStartupTags)

    {

        if (this.IsMsAjax)

        {

            if (RegisterStartupScriptMethod == null)

                RegisterStartupScriptMethod = scriptManagerType.GetMethod("RegisterStartupScript");

 

            RegisterStartupScriptMethod.Invoke(null, new object[5] { control, type, key, script, addStartupTags });

        }

        else

            this.clientScript.RegisterStartupScript(type, key, script, addStartupTags);

 

    }

 

    /// <summary>

    /// Registers a script include tag into the page for an external script url

    /// </summary>

    /// <param name="control"></param>

    /// <param name="type"></param>

    /// <param name="key"></param>

    /// <param name="url"></param>

    public void RegisterClientScriptInclude(Control control, Type type, string key, string url)

    {

        if (this.IsMsAjax)

        {

            if (RegisterClientScriptIncludeMethod == null)

                RegisterClientScriptIncludeMethod = scriptManagerType.GetMethod("RegisterClientScriptInclude");

 

            RegisterClientScriptIncludeMethod.Invoke(null, new object[4] { control,  type, key, url });

        }

        else

            this.clientScript.RegisterClientScriptInclude( type, key, url);

    }

 

 

    /// <summary>

    /// Adds a script include tag into the page for WebResource.

    /// </summary>

    /// <param name="control"></param>

    /// <param name="type"></param>

    /// <param name="resourceName"></param>

    public void RegisterClientScriptResource(Control control, Type type, string resourceName)

    {

        if (this.IsMsAjax)

        {

            if (RegisterClientScriptResourceMethod == null)

                RegisterClientScriptResourceMethod = scriptManagerType.GetMethod("RegisterClientScriptResource");

 

            RegisterClientScriptResourceMethod.Invoke(null, new object[3] { control, type, resourceName });

        }

        else

            this.clientScript.RegisterClientScriptResource(type,resourceName);

    }

 

 

    public string GetWebResourceUrl(Control control, Type type, string resourceName)

    {

        //if (this.IsMsAjax)

        //{

        //    if (GetWebResourceUrlMethod == null)

        //        GetWebResourceUrlMethod = scriptManagerType.GetMethod("GetScriptResourceUrl");

 

        //    return GetWebResourceUrlMethod.Invoke(null, new object[2] { resourceName, control.GetType().Assembly }) as string;

        //}

        //else

        return this.clientScript.GetWebResourceUrl(type, resourceName);

    }

 

}

 

The code basically checks to see whether the MS Ajax assembly can be accessed as a type and if so assumes MS Ajax is installed. This is not quite optimal – it’d be better to know whether a ScriptManager is actually being used on the current page, but without scanning through all controls (slow) I can’t see a way of doing that easily.

 

The control caches each of the MethodInfo structures to defer some of the overhead in making the Reflection calls to the ScriptManager methods. I don’t think that Reflection here is going to cause much worry about overhead unless you have a LOT of calls to these methods (I suppose it’s possible if you have lots of resources – think of a control like FreeTextBox for example). Even then the Reflection overhead is probably not worth worrying about.

 

To use this class all calls to ClientScript get replaced with call this class instead. So somewhere during initialization of the control I add:

 

protected override void OnInit(EventArgs e)

{

    this.ClientScriptProxy = ClientScriptProxy.Current;

    base.OnInit(e);

}

 

And then to use it:

 

this.ClientScriptProxy.RegisterClientScriptInclude(this,this.GetType(),

           ControlResources.SCRIPTLIBRARY_SCRIPT_RESOURCE,

           this.ResolveUrl(this.ScriptLocation));

 

Notice the first parameter is the control instance (typically this) just like the ScriptManager call, so there will be a slight change of parameters when changing over from ClientScript code.

 

Once I added this code to my controls the problems with UpdatePanel went away and it started rendering properly again even with the controls hosted inside of the UpdatePanels.


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·在C#中使用代理的方式触发事件-.NET教程,C#语言
·Java socket编程入门[1]-JSP教程,Java技巧及代码
·VB.NET 操作 ACCESS OLE 字段内容-.NET教程,VB.Net语言
·实例学习Spring和Hibernate的一点点体会-JSP教程,资料/其它
·《XML指南》下载[CHM格式-.NET教程,XML应用
·锂离子动力电池待解决的使用技术问题
·ASP.NET下的Page Controller以及Template Method-.NET教程,Asp.Net开发
·用C#实现WEB浏览器-.NET教程,C#语言
·在Visual Studio 2005和ASP.NET 2.0中使用强类型数据存取-.NET教程,Asp.Net开发
·ASP和C#隐藏文件下载路径的方法-ASP教程,ASP技巧
最新文章
·论arp攻击防制的基本方法_安全在线教程
·七种最不安全的网络管理员_安全在线教程
·windows网络安全其实我们只差五步_安全在线教程
·确保无线网络安全实施的几种技术规范_安全在线教程
·从两大方面阻止域名劫持_安全在线教程
·对网站做一些简单的seo处理_seo网站优化
·如何减轻ddos攻击危害_安全在线教程
·防火墙封阻应用攻击的八项技术_安全在线教程
·防火墙的来历及应用现状_安全在线教程
·浅析ids与ips共生与发展_安全在线教程
相关主题
  • updatepanel与urlrewrite_asp.net技巧
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭