如何将使用Ajax webmethods的ASP.NET页面转换为支持Ajax的服务器控件?

如何将使用Ajax webmethods的ASP.NET页面转换为支持Ajax的服务器控件?,asp.net,ajax,clientscript,servercontrol,Asp.net,Ajax,Clientscript,Servercontrol,在中,Dave Ward创建了一个页面,在标签中显示服务器日期,而不使用“更新”面板 我试图学习如何创建使用ajax进行部分回发的servercontrols,其中控件内的方法是从同一控件生成的clientscript调用的,我认为,学习如何将此页面转换为服务器控件将有助于我理解servercontrols使用什么代替webmethods向clientscript公开其方法 我完全按照文章所示创建了页面、codebehind和javascript,并使示例正常工作 因此,为了开始尝试将其转换为服

在中,Dave Ward创建了一个页面,在标签中显示服务器日期,而不使用“更新”面板

我试图学习如何创建使用ajax进行部分回发的servercontrols,其中控件内的方法是从同一控件生成的clientscript调用的,我认为,学习如何将此页面转换为服务器控件将有助于我理解servercontrols使用什么代替webmethods向clientscript公开其方法

我完全按照文章所示创建了页面、codebehind和javascript,并使示例正常工作

因此,为了开始尝试将其转换为服务器控件,我将Dave的页面Javascript移动到一个文件中,~tests/JScript.js:

 function UpdateTime() {
   PageMethods.GetCurrentDate(OnSucceeded, OnFailed); 
 }
 
 function OnSucceeded(result, userContext, methodName) {
   $get('Literal1').innerHTML = result; 
 }
 
 function OnFailed(error, userContext, methodName) {
   $get('Literal1').innerHTML = "An error occured.";
 }
并将以下类放入我的应用程序代码中:

namespace foo
{
    /// <summary>
    /// Summary description for ServerControlTest
    /// </summary>
    public class ServerControlTest : CompositeControl, IScriptControl
    {
        ScriptManager sm;
        protected override void OnPreRender(EventArgs e)
        {
            if (!this.DesignMode)
            {
                // Test for ScriptManager and register if it exists
                sm = ScriptManager.GetCurrent(Page);

                if (sm == null)
                    throw new HttpException("A ScriptManager control must exist on the current page.");

                sm.RegisterScriptControl(this);
                sm.EnablePageMethods = true;
            }

            base.OnPreRender(e);
        }

        protected override void OnLoad(EventArgs e)
        {
            Literal lit = new Literal();
            lit.Text = "<span ID=\"Literal1\" runat=\"server\">test</span><input id=\"Button1\" type=\"button\" value=\"button\"  onclick=\"UpdateTime();\" />";

            this.Controls.Add(lit);
        }
        protected override void Render(HtmlTextWriter writer)
        {
            if (!this.DesignMode)
                sm.RegisterScriptDescriptors(this);

            base.Render(writer);
        }

        [WebMethod]
        public static string GetCurrentDate()
        {
            return DateTime.Now.ToString();
        }

        #region IScriptControl Members

        IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
        {
            return null;
        }

        IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
        {
            ScriptReference reference = new ScriptReference();
            reference.Path = ResolveClientUrl("~/tests/JScript.js");

            return new ScriptReference[] { reference };
        }

        #endregion
    }
}
名称空间foo
{
/// 
///ServerControlTest的摘要说明
/// 
公共类ServerControlTest:CompositeControl,IScriptControl
{
脚本管理器sm;
受保护的覆盖无效OnPreRender(EventArgs e)
{
如果(!this.DesignMode)
{
//测试ScriptManager并注册它(如果存在)
sm=ScriptManager.GetCurrent(第页);
if(sm==null)
抛出新的HttpException(“当前页面上必须存在ScriptManager控件。”);
sm.RegisterScriptControl(此);
sm.EnablePageMethods=true;
}
基于预渲染(e);
}
受保护的覆盖无效加载(事件参数e)
{
Literal lit=新的Literal();
lit.Text=“测试”;
this.Controls.Add(点亮);
}
受保护的覆盖无效渲染(HtmlTextWriter编写器)
{
如果(!this.DesignMode)
sm.RegisterScript描述符(本);
base.Render(writer);
}
[网络方法]
公共静态字符串GetCurrentDate()
{
return DateTime.Now.ToString();
}
#区域IScriptControl成员
IEnumerable IScriptControl.GetScriptDescriptors()
{
返回null;
}
IEnumerable IScriptControl.GetScriptReferences()
{
ScriptReference=新建ScriptReference();
reference.Path=ResolveClientUrl(“~/tests/JScript.js”);
返回新的ScriptReference[]{reference};
}
#端区
}
}
现在,在我的示例页面中,当我单击按钮时,出现以下错误: 未定义页面方法 [Break on this error]PageMethods.GetCurrentDate(OnSucceeded,OnFailed)


如何从控件注册的clientscript调用GetCurrentDate?

从v3.5开始,实际上还没有针对服务器控件的方法实现AJAX回调的完全封装方法。这是一个非常令人沮丧的限制


最常见的解决方案是在服务器控件的程序集中创建HttpHandler,然后要求在web.config中注册该处理程序。例如,看看ASP.NET AJAX的ScriptResource.axd是如何连接到ASP.NET AJAX 1.0的web.config中的。

谢谢你的回答,Dave。我感到沮丧,想知道我错过了什么。到目前为止,你博客上的所有内容都对我很有帮助。有人知道如何设置这样的http处理程序吗?我还对具体的实现细节感兴趣。