Asp.net WebUIValidation.js在CompositeScript和UpdatePanel中时会在异步调用中重新加载
我的场景:Asp.net WebUIValidation.js在CompositeScript和UpdatePanel中时会在异步调用中重新加载,asp.net,updatepanel,scriptmanager,scriptresource.axd,Asp.net,Updatepanel,Scriptmanager,Scriptresource.axd,我的场景: 我在UpdatePanel中有一个验证器 我想合并我的脚本,因此我在ScriptManager中使用CompositeScript,并包含对WebUIValidation.js 我正在使用.NET4.0 我的问题: 当我异步更新异步响应中的面板时,.NET加载WebUIValidation.js(在Scriptresource.axd文件中),即使它已加载到初始CompositeScript生成的脚本中。这是一个问题,因为我的自定义代码劫持了WebUIValidation.js
- 我在
中有一个验证器UpdatePanel
- 我想合并我的脚本,因此我在
中使用ScriptManager
,并包含对CompositeScript
WebUIValidation.js
- 我正在使用.NET4.0
- 当我异步更新异步响应中的面板时,.NET加载
(在WebUIValidation.js
文件中),即使它已加载到初始Scriptresource.axd
生成的脚本中。这是一个问题,因为我的自定义代码劫持了CompositeScript
中的一些函数,而异步响应会覆盖我的劫持WebUIValidation.js
- 如果将
中对ScriptManager
的引用移动到WebUIValidation.js
,则没有问题Scripts
- 如果将
作为WebUIValidation.js
中的唯一项(我知道这是毫无意义的),那么就没有问题了CompositeScript
- 其他.NET库脚本(例如
WebForm.js
- 异步响应中加载了
,而它已经包含在WebUIValidation.js
中,这有什么原因吗?CompositeScript
WebUIValidation.js
可能不由ScriptManager
处理。有人能证实这一点吗
要复制,请使用以下两个文件
test1.js
// To be added to the composite script
console.log('Test 1 Loaded');
private void ProcessFocus(HtmlTextWriter writer) {
// Roughly stolen from Whidbey Page.cs
if (_requireFocusScript) {
Debug.Assert(ClientSupportsFocus, "If ClientSupportsFocus is false then we never should have set _requireFocusScript to true.");
string focusedControlId = String.Empty;
// Someone calling SetFocus(controlId) has the most precedent
if (!String.IsNullOrEmpty(_focusedControlID)) {
focusedControlId = _focusedControlID;
}
else {
if (_focusedControl != null && _focusedControl.Visible) {
focusedControlId = _focusedControl.ClientID;
}
}
if (focusedControlId.Length > 0) {
// Register focus script library
string focusResourceUrl = _owner.GetScriptResourceUrl("Focus.js", typeof(HtmlForm).Assembly);
EncodeString(writer, ScriptBlockToken, "ScriptPath", focusResourceUrl);
// *********** THIS ENCODESTRING OUTPUTS THE PROBLEM !!!
// Send the target control ID to the client
EncodeString(writer, FocusToken, String.Empty, focusedControlId);
}
}
}
test.aspx
<%@ Page Language="vb" AutoEventWireup="false" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title></title>
</head>
<body>
<script language="VB" runat="server" runat="server">
Protected Sub ButtonClicked(ByVal sender As Object, ByVal e As System.EventArgs) Handles TestButton.Click
ButtonClickFeedback.Text = "Button clicked At " & Date.Now.ToString & "; Look at the scripts in your Developer Tools, there is now a separate script for WebUIValidation.js loaded, in spite of the composite script."
End Sub
</script>
<form runat="server">
<asp:ScriptManager runat="server">
<CompositeScript>
<Scripts>
<asp:ScriptReference Path="~/test.js" />
<asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" />
</Scripts>
</CompositeScript>
</asp:ScriptManager>
<h1>WebUIValidation.js, CompositeScript and UpdatePanel test</h1>
<asp:UpdatePanel runat="server" ID="ButtonUpdatePanel">
<ContentTemplate>
<asp:Label runat="server" >This is a section with a validator that is within an UpdatePanel. If you look at the scripts loaded, you will see the composite script in the detail.</asp:Label>
<asp:Textbox ID="TestInputForValidator" runat="server" Text="This is populated so it will validate"/>
<asp:RequiredFieldValidator runat="server" ControlToValidate="TestInputForValidator" ErrorMessage="You must write something" /><br />
<asp:Button ID="TestButton" Text="Click Me!" runat="server" /><br />
<asp:Literal ID="ButtonClickFeedback" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="TestButton" />
</Triggers>
</asp:UpdatePanel>
</form>
</body>
</html>
受保护的子按钮单击(ByVal sender作为对象,ByVal e作为System.EventArgs)处理TestButton。单击
ButtonClickFeedback.Text=“Button clicked At”&Date.Now.ToString&“查看开发人员工具中的脚本,现在已为WebUIValidation.js加载了一个单独的脚本,尽管使用了复合脚本。”
端接头
WebUIValidation.js、CompositeScript和UpdatePanel测试
这是UpdatePanel中包含验证器的部分。如果查看加载的脚本,您将看到详细的复合脚本。
如果您使用开发人员工具检查加载的脚本,则应该会看到在单击按钮后加载的其他Scriptresource.axd(包含WebUIValidation.js),尽管存在带有复合脚本的Scriptresource.axd。test.js只是一个模拟复合脚本思想的示例js文件。分享我对为什么再次加载这些脚本的调查(WebUIValidation.js或Focus.js)。我刚刚找到了Focus.js 首先,http请求的发起在更新面板生成的部分更新中。如果您查看对异步xhr POST请求的响应,您将看到如下内容。请注意,几乎在最后是ScriptResource.axd url。这是由客户端的ajax框架处理的,因为它是一个带有路径的脚本块,所以会被加载:
1|#||4|2999|updatePanel|ctl00_LoginContent_ctl00|
<div id="ctl00_LoginContent_...">[...html content here]</div>|
0|hiddenField|__LASTFOCUS||
0|hiddenField|__EVENTTARGET||
0|hiddenField|__EVENTARGUMENT||
904|hiddenField|__VIEWSTATE|UdWhNvH6wpBcPOigY[...]SIphbw==|
8|hiddenField|__VIEWSTATEGENERATOR|25748CED|
176|hiddenField|__EVENTVALIDATION|q+FUEVGVj+t[...]AzAm|
0|asyncPostBackControlIDs|||
0|postBackControlIDs|||
26|updatePanelIDs||tctl00$LoginContent$ctl00,|
0|childUpdatePanelIDs|||
25|panelsToRefreshIDs||ctl00$LoginContent$ctl00,|
2|asyncPostBackTimeout||90|
14|formAction||./Default.aspx|
119|scriptBlock|ScriptContentNoTags|function PopulateTimeZoneOffset(){[my own js here...]}|
154|scriptBlock|ScriptPath|/ScriptResource.axd?d=Uup1Lt[...]q450&t=ffffffffd4ee116f|
31|focus||ctl00_LoginContent_LoginControl|
我们深入了解了Page.ProcessRequest,现在又深入到Page.Render、RenderPageCallback和ProcessFocus。结尾附近突出显示的EncodeString直接写入写入程序,例如“len | type | id | content |”,包括writer.Write(content)代码>其中内容是“/ScriptResource.axd?d=Uup1IW…q450&t=ffffffffffd4ee116f”
。没有检查此脚本是否已向ScriptManager注册,它没有调用ScriptManager.RegisterXXXX
因此,在我看来,这就是为已经加载的内容获取另一个http请求的原因。ProcessFocus是作为“Render”的一部分完成的,使用任何ScriptManager功能都为时已晚
我想不出一种方法来避免这个http请求(除了不使用.net框架中的任何SetFocus
类型)
(运行VS 2015、.net framework 4.6.2、ajax控制工具包17.1)@alerygy:您有没有回避过这个问题?我今天也遇到了类似的问题。@TCM-我能够解决这个问题的唯一方法是将WebUIValidation.js移动到ScriptManager
的
部分,而不是在CompositeScripts
下-这意味着我有两个脚本调用(ScriptResource.axd中的composite和单个WebUIValidation)在网页上。不太理想,但问题似乎在于WebUIValidation.js的管理方式。@alergy我也遇到了同样的问题,但将WebUIValidation.js
移动到Script
部分,而不使用CompositeScripts
,因为父级并没有解决问题。在部分回发后,ScriptResource.axd
仍然被加载,因此我覆盖的验证函数将丢失。我得到了Focus.js(以及WebUIValidation.js)的相同内容