gpt4 book ai didi

asp.net - 在 CompositeScript 和 UpdatePanel 中时,WebUIValidation.js 在异步调用中重新加载

转载 作者:行者123 更新时间:2023-12-02 14:03:27 25 4
gpt4 key购买 nike

我的场景:

  • 我在 UpdatePanel 中有一个验证器。
  • 我想组合我的脚本,因此我在 ScriptManager 中使用 CompositeScript,并包含对 WebUIValidation.js 的引用
  • 我正在使用 .NET 4.0

我的问题:

  • 当我异步更新面板时,.NET 会在异步响应中加载 WebUIValidation.js(在 Scriptresource.axd 文件中),即使它已加载到最初的 CompositeScript 生成的脚本。这是一个问题,因为我有自定义代码劫持了 WebUIValidation.js 中的某些函数,并且异步响应覆盖了我的劫持。
  • 如果将对 WebUIValidation.js 的引用移至 ScriptManager 中的 Scripts,就没有问题。
  • 如果您将 WebUIValidation.js 作为 CompositeScript 中的唯一项目(我知道毫无意义),那么就没有问题。
  • 其他 .NET 库脚本不会发生这种异步重新加载,例如WebForm.js

我想了解什么:

  • WebUIValidation.js 已包含在 CompositeScript 中时,是否会在异步响应中加载它?

有人发布了similar (but not duplicate) issue今天,并且转向说 WebUIValidation.js 可能不会由 ScriptManager 处理。谁能验证一下吗?

要复制,请使用以下两个文件

test1.js

// To be added to the composite script
console.log('Test 1 Loaded');

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>

如果您使用开发人员工具来检查正在加载的脚本,您应该会看到在单击按钮后加载了一个额外的 Scriptresource.axd(包含 WebUIValidation.js),尽管存在 Scriptresource。 axd 与复合脚本。 test.js 只是一个示例 js 文件,用于模拟复合脚本的思想。

最佳答案

分享我对为什么再次加载这些脚本(WebUIValidation.js 或 Focus.js)的调查。我现在刚刚找到 Focus.js。

首先,http请求的起源是更新面板生成的部分更新。如果您查看异步 xhr POST 请求的响应,您将看到类似这样的内容。请注意几乎在末尾的 ScriptResource.axd url。这是由客户端的 ajax 框架处理的,因为它是一个带有路径的脚本 block ,所以它会被加载:

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|

现在调试服务器端代码,从 https://referencesource.microsoft.com/ 加载 .net 程序集符号(使用此处描述的 VS 配置)。

PageRequestmanager.cs

    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);
}
}
}

我们已经深入了解了 Page.ProcessRequest,现在进入了 Page.Render、RenderPageCallback 和 ProcessFocus。靠近末尾突出显示的 EncodeString 直接向编写器写入“len|type|id|content|”之类的内容,包括 writer.Write(content); 其中 content“/ScriptResource.axd?d=Uup1IW...q450&t=ffffffffd4ee116f”。不会检查该脚本是否已在 ScriptManager 中注册,它不会调用 ScriptManager.RegisterXXXX。

所以在我看来,这就是为已加载的内容获取另一个 http 请求的原因。 ProcessFocus 是作为“渲染”的一部分完成的,太晚了,无法使用任何 ScriptManager 功能。

我想不出一种方法来避免此 http 请求(除了不使用 .net 框架中的任何 SetFocus 类型的东西)。

(运行VS 2015,.net框架4.6.2,ajax控制工具包17.1)

关于asp.net - 在 CompositeScript 和 UpdatePanel 中时,WebUIValidation.js 在异步调用中重新加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20999104/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com