【问题标题】:AjaxControlToolkit issue in Async WebForms pages异步 WebForms 页面中的 AjaxControlToolkit 问题
【发布时间】:2020-02-09 23:09:25
【问题描述】:

运行异步任务的 WebForms 页面中的 AjaxControlToolkit 扩展程序(或任何其他扩展程序)存在问题。如果您的扩展程序最初是不可见的,并且您运行了一个异步任务以使其可见(例如,如果应根据您异步读取的数据确定可见性),那么您将获得以下 System.ArgumentException:

Extender control '[ControlID]' is not a registered extender control.
Extender controls must be registered using RegisterExtenderControl() before calling RegisterScriptDescriptors().

经过一些分析,这是造成这种情况的原因。

  1. ExtenderControl 基类,它所有的 AjaxControlToolkit 扩展器 子类,在其中调用ScriptManager.RegisterExtenderControl() OnPreRender 方法。而且,ScriptManager 会抛出异常 如果RegisterExtenderControl() 在除此之外的任何阶段被调用 预渲染。
  2. 对于在 PreRender 阶段不可见的控件, OnPreRender 方法将不会被调用,因此扩展程序 控件不会被注册。
  3. WebForms 页面在 PreRender 阶段之后运行所有异步任务,并且 在渲染阶段之前。所以,如果你让你的扩展器在 异步任务,那么它将在 PreRender 中不可见 阶段,并且仅在渲染阶段。
  4. 最后,扩展器控制调用 ScriptManager.RegisterScriptDescriptors() 在渲染阶段, 由于没有控制而引发上述异常 在 PreRender 阶段注册。

有没有人找到解决方法或解决方法?

这似乎是 WebForms 中的一个巨大限制,您无法在同一页面中有效地同时使用异步任务和扩展器控件。

以下是说明此问题的示例网页。

<%@ Page Async="true" MasterPageFile="~/Site.Master" Language="C#" AutoEventWireup="true" Inherits="System.Web.UI.Page" %>
<%@ Import Namespace="System.Threading.Tasks" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <asp:Panel ID="Panel1" runat="server">
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
        <ajaxToolkit:CalendarExtender ID="CalendarExtender1" runat="server" TargetControlID="TextBox1" />
    </asp:Panel>
</asp:Content>

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        Panel1.Visible = false;
        RegisterAsyncTask(new PageAsyncTask(ReadAsync));
    }

    // Making the panel visible below will result in the following exception:
    // Extender control 'CalendarExtender1' is not a registered extender control.
    // Extender controls must be registered using RegisterExtenderControl() before calling RegisterScriptDescriptors().
    private async Task ReadAsync()
    {
        Panel1.Visible = true;
        await Task.CompletedTask;
    }
</script>

【问题讨论】:

标签: asp.net asynchronous webforms ajaxcontroltoolkit


【解决方案1】:

根据在此处发布到此问题的建议 https://forums.asp.net/p/2163988/6293999.aspx?p=True&t=637169211245961059 在这里https://github.com/DevExpress/AjaxControlToolkit/issues/523,我想出了一个通用的方法来解决这个问题。

基本上,您的页面将跟踪具有扩展器的控件,并且可以在异步任务中运行时更改其可见性。然后它将在适当的时间在 PreRender 上使这些控件暂时可见以避免错误,然后在 PreRender 完成后根据需要隐藏它们。这里的关键是使用页面新的SetControlVisible方法来设置控件的可见性。

此解决方法的完整源代码发布在此处:https://github.com/Xomega-Net/XomegaFramework/blob/master/src/Xomega.Framework.Web/Views/WebPage.cs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    相关资源
    最近更新 更多