询问者
ASP.NET AJAX 常见问题

常规讨论
-
3. 如何在部分回传(partial PostBack)中的具体阶段去执行一项动作?
4. 为什么收到PageRequestManagerParserErrorException 异常?
5. 如何在特定用户控件中注册一个控件的事件作为UpdatePanel的触发器?
6. 如何在一个用户控件中注册一个控件的事件作为另一个控件中的UpdatePanel的触发器?
7. 如何从ContentPage动态添加ScriptManager 和 UpdatePanel 到MasterPage?
8. HyperLink能否作为UpdatePanel的触发器?
9. 如何从不同的窗体中触发部分回传(partial PostBack)?
11. 在PageMethod(页面方法)中为何不能访问页面控件?
If you have any feedback on this FAQ please send it to fbmsdn@microsoft.com
全部回复
-
为了在生产服务器上部署许可AJAX的网站,下面是我们需要在其上履行的一些事项。
1. 在服务器上安装AJAX扩展
2. 在IIS中把虚拟路径配置为应用程序
3. 应用程序的ASP.NET 版本设置为2.0
4. 在web.config中添加一些条目去注册必要的程序集,HttpHandlers 等
最容易的方法是使用ASP.NET AJAX-Enabled Web Site模板创建网站,如果需要更新现存网站,请手工编辑web.config文件,这个文档(http://asp.net/AJAX/Documentation/Live/ConfiguringASPNETAJAX.aspx)和这两个视频教程(How Do I: ASP.NET AJAX Enable an Existing Web Service?, How Do I: Add ASP.NET AJAX Features to an Existing Web Application? )解释了什么是必须做的及原因。
状态代码500的错误表明在服务器设法处理请求时产生了问题,这儿可能有各种不同的原因,问题在于如何找到错误的真正原因。
下面是查找它的两种方法:
1. 在代码中设置一个断点去负责处理请求,然后通过调试查明抛出的异常。
2. 真实的错误信息通常在响应中返回,我们可以使用HTTP嗅探器(例如:Fiddler)在客户端和服务器的往来中窥探以找到错误信息。
3. 如何在部分回传(partial PostBack)中的具体阶段去执行一项动作? [回到顶端]
在微软AJAX库中有类似与在服务器上的页面生命周期模型的客户端生命周期模型,开发者可以添加不同的事件处理程序去在具体阶段执行具体操作,例如,在beginRequest 事件处理程序中刚好在页面回传的时候禁用一个按钮,接着在endRequest事件处理程序中再一次启用按钮
这份文档(AJAX Client Life-Cycle Events)包含了那些事件顺序的完整描述,及如何运用它们。
相关主题:
http://forums.asp.net/t/1109705.aspx
4. 为何获得PageRequestManagerParserErrorException 异常? [回到顶端]
当我们使用UpdatePanel时可能产生这个异常。关于部分回传,请求和正常回传是完全一样的,不同之处在于请求和XmlHttpRequest一同发出。另一个显著区别是请求以特定格式回复。
典型地,回复仅包含UpdatePanel的要更新的内容,并且一定要遵循特定的格式,以致它可以被客户端库解析去更新页面
如果你设法输出一些并附加Response.Write,服务器跟踪,或者用HTTP模块修改输出,回复将不再遵守格式,那么客户端库不能再解析它,因此异常发生。
为了摆脱这个问题,当页面中有UpdatePanel时,我们不应当使用上述功能。
相关主题:
http://forums.asp.net/p/1140794/1844602.aspx
5. 如何在特定用户控件中注册一个控件的事件作为UpdatePanel的触发器? [回到顶端]
最好的解决方案是提升控件的事件作为该用户控件的自定义事件,接着注册该用户控件的自定义事件作为UpdatePanel的触发器
1.在该用户控件中定义自定义委托和事件
2.在将提升的事件中引发自定义事件
3.注册用户控件的自定义事件作为UpdatePanel的触发器,就像通常的控件那样
如下例:
<%@ Control Language="C#" ClassName="TestUc" %>
<script runat="server">
protected void lb_Command(object sender, CommandEventArgs e)
{ // 提升command事件作为TestCustomEvent
if (TestCustomEvent != null) TestCustomEvent(this, e);
}
</script>
<asp:LinkButton ID="LinkButton1" runat="server" CommandArgument="LinkButton1" OnCommand="lb_Command">LinkButton1</asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CommandArgument="LinkButton2" OnCommand="lb_Command">LinkButton2</asp:LinkButton>
<%@ Page Language="C#" %>
<%@ Register src="TestUc.ascx" TagName="TestUc" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void TestUc1_TestCustomEvent(object sender, CommandEventArgs e)
{
Label1.Text = DateTime.Now.ToString();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Trigger UpdatePanel</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<uc1:TestUc id="TestUc1" runat="server" OnTestCustomEvent="TestUc1_TestCustomEvent">
</uc1:TestUc>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="TestUc1" EventName="TestCustomEvent" />
</Triggers>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
相关主题:
http://forums.asp.net/t/1138191.aspx
http://forums.asp.net/t/1123812.aspx
http://forums.asp.net/t/1141328.aspx
http://forums.asp.net/t/1175921.aspx6. 如何在一个用户控件中注册一个控件的事件作为另一个控件中的UpdatePanel的触发器? [回到顶端]
为了实现这个,我们可以首先定义用户属性去显示用户控件上UpdatePanel的隐藏触发器的客户端ID(比如"UserControlA"),在其它的用户控件上(比如"UserControlB"),我们将会引发隐藏触发器控件的click事件。
1. 定义自定义属性存储UpdatePanel的隐藏触发器控件的客户端ID(Gallery用户控件的Button1clientID属性):
<%@ Control Language="C#" ClassName="Gallery" %>
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
}
public string Button1clientID
{
get
{
return Button1.ClientID;
}
}
</script>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
<div style="visibility: hidden">
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click"
UseSubmitBehavior="false" Text="Button" /></div>
</ContentTemplate>
</asp:UpdatePanel>
2. 在其它用户控件中定义自定义属性(Upload用户控件的Button1clientID属性):
<%@ Control Language="C#" ClassName="Upload" %>
<script runat="server">
private string buttonclientID = "";
public string Button1clientID
{
set
{
buttonclientID = value;
}
}
</script>
3. 在 page_Load中设置Upload1.Button1clientID = Gallery1.Button1clientID:
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Upload1.Button1clientID = Gallery1.Button1clientID;
}
</script>
4. 手工触发隐藏触发器控件的click事件:
<script type="text/javascript">
function submitForm()
{
document.getElementById("<%=buttonclientID %>").click();
}
</script>
<button onclick="javascript:submitForm();">Upload</button>
完整事例代码:
http://forums.asp.net/p/1117746/1739422.aspx#1739422
相关主题:
http://forums.asp.net/t/1117746.aspx
http://forums.asp.net/t/1136932.aspx -
7. 如何从ContentPage动态添加ScriptManager 和 UpdatePanel 到MasterPage? [回到顶端]
ScriptManager必须被添加在需要它的页面的初始化阶段。否则,InvalidOperationException异常将被抛出(解释到页面上缺少ScriptManager)。最好在initialization之前的Page_PreInit中添加。
protected void Page_PreInit(object sender, EventArgs e)
{
HtmlForm form1 = (HtmlForm)Master.FindControl("form1");
ScriptManager sm = new ScriptManager();
sm.ID = "ScriptManager1";
form1.Controls.AddAt(0, sm);
// 添加 UpdatePanel 并且把已经存在的控件转移其上
UpdatePanel panel = new UpdatePanel();
panel.ID = "upMaster";
Control ctrl = ((Control)Master.FindControl("TextBox1"));
panel.ContentTemplateContainer.Controls.Add(uc);
form1.Controls.Add(panel);
}
相关主题:
http://forums.asp.net/t/1165939.aspx
http://forums.asp.net/t/1160425.aspx
http://forums.asp.net/t/1163971.aspx8. HyperLink能否作为UpdatePanel的触发器? [回到顶端]
不可以。请参考文档:http://www.asp.net/AJAX/documentation/live/mref/P_System_Web_UI_UpdatePanelControlTrigger_ControlID.aspx。触发器一定要执行INamingContainer, IPostBackDataHandler, 或者 IPostBackEventHandler 接口。HyperLink并没有实现他们中任何一个。
同时可参考:
相关主题:
http://forums.asp.net/t/1138804.aspx
http://forums.asp.net/t/1099204.aspx
http://forums.asp.net/t/1170105.aspx许多案例是我们需要从不同窗体触发部分回传,例如:通过IFrame在父窗体触发部分回传,通过弹出窗体在opener触发部分回传。
我们可以在PageA上添加不可见按钮(如Button1),并且设置它为UpdatePanel的触发器,接着我们需要从PageB获得这个按钮的一个引用,并激发click去触发部分回传,可用如下javascript实现:
"window.parent.document.getElementById('Button1').click()"
"window.opener.document.getElementById('Button1').click()"这是完整事例代码:
http://forums.asp.net/p/1162285/1927000.aspx#1927000
相关主题:
http://forums.asp.net/t/1162285.aspx
http://forums.asp.net/t/1117770.aspx
http://forums.asp.net/t/1169365.aspx10. 如何在客户端操作AJAX Timer 控件? [回到顶端]
在客户端管理Timer控件,我们需要用这样的$find方法去引用客户端组件:
var timer = $find("Timer1");
接着,我们可以调用set_interval方法去设置Timer控件的时间间隔,_stopTimer方法去停止它,_startTimer方法启动它。
如下例:
<asp:Timer ID="Timer1" runat="server" Interval="3000">
</asp:Timer>
<input id="Button1" type="button" value="ChangeInterval" onclick="setTimer();"/>
<input id="Button2" type="button" value="Start" onclick="startTimer();"/>
<input id="Button3" type="button" value="Stop" onclick="stopTimer();"/>
<script type="text/javascript">
function setTimer()
{
var timer = $find("Timer1");
timer.set_interval(100);
}
function startTimer()
{
var timer = $find("Timer1");
timer._startTimer();
}
function stopTimer()
{
var timer = $find("Timer1");
timer._stopTimer();
}
</script>
相关主题:
http://forums.asp.net/t/1159648.aspx
http://forums.asp.net/t/1163431.aspx11. 在PageMethod(页面方法)中为何不能访问页面控件? [回到顶端]
通过反射调用PageMethod。
当服务器收到PageMethod的请求时,它用System.Web.Script.Services.RestHandler类中的ProcessRequest(HttpContext上下文)方法去服务请求。反射在内部被使用去调用公共和静态PageMethod。它不能通过该页面的实例去访问。同时,这个请求并不会经历对.aspx页面的正常请求的确定的生命周期。因此,在PageMethod的内部不能访问页面上的控件。
AJAX 扩展官方网站
http://www.asp.net/AJAX/AJAX 扩展文档
http://www.asp.net/AJAX/documentation/AJAX视频教程
http://www.asp.net/learn/AJAX-videos/AJAX 控件包项目
http://www.codeplex.com/Wiki/View.aspx?ProjectName=AtlasControlToolkitAJAX 控件包在线事例
http://www.asp.net/AJAX/AJAXcontroltoolkit/samples/如何播放动画?
http://blogs.msdn.com/phaniraj/archive/2007/04/13/animations-how-many-ways-do-i-call-thee.aspx如何: 在页面中再使用动画扩展
http://blogs.msdn.com/phaniraj/archive/2007/08/15/how-to-re-use-animation-extenders-in-a-page.aspx如何: 操作页面的AJAX控件扩展的所有实例
http://blogs.msdn.com/phaniraj/archive/2007/08/15/how-to-re-use-animation-extenders-in-a-page.aspx如何: 在AutoCompleteExtender中使用键-值对
http://blogs.msdn.com/phaniraj/archive/2007/06/19/how-to-use-a-key-value-pair-in-your-autocompleteextender.aspxMs AJAX AnimationExtender的脚本动画
http://blogs.msdn.com/phaniraj/archive/2007/05/31/scripting-animations-from-the-ms-AJAX-animationextender.aspx如何 : 在MS AJAX TabControl中通过JavaScript改变Tab的可见性
http://blogs.msdn.com/phaniraj/archive/2007/04/16/howto-change-visible-tab-using-javascript-in-the-ms-AJAX-tabcontrol.aspx通过 JavaScript显示和隐藏ModalPopupExtender
http://blogs.msdn.com/phaniraj/archive/2007/02/20/show-and-hide-modalpopupextender-from-javascript.aspx通过客户端改变AutoCompleteExtender 的ServiceMethods 和 Web Service
http://blogs.msdn.com/phaniraj/archive/2007/02/16/change-servicemethods-and-web-service-for-the-autocompleteextender-from-client-side.aspx
If you have any feedback on this FAQ please send it to fbmsdn@microsoft.com