Существует проблема с расширителями AjaxControlToolkit (или любыми другими расширителями) на страницах WebForms, на которых выполняются задачи Asyn c. Если ваш расширитель изначально не видим, и вы запускаете асинхронную задачу c, в которой вы делаете ее видимой (например, если видимость должна быть определена на основе данных, которые вы читаете асинхронно), то вы получите следующее исключение System.ArgumentException:
Extender control '[ControlID]' is not a registered extender control.
Extender controls must be registered using RegisterExtenderControl() before calling RegisterScriptDescriptors().
После некоторого анализа вот что вызывает это.
- Базовый класс ExtenderControl, который все подклассы расширителей AjaxControlToolkit, вызывают
ScriptManager.RegisterExtenderControl()
в своем методе OnPreRender
. Кроме того, ScriptManager сгенерирует исключение, если RegisterExtenderControl()
вызывается на любом этапе, кроме PreRender. - Для элементов управления, которые не видны на этапе PreRender, метод
OnPreRender
вызываться не будет, и, следовательно, Управление расширением не будет зарегистрировано. - Страницы WebForms запускают все асинхронные c задачи после этапа PreRender и до этапа Render. Таким образом, если вы сделаете свой расширитель видимым в асинхронной задаче c, то он не будет виден еще на этапе PreRender и только на этапе рендеринга.
- Наконец, элементы управления расширителем вызывают
ScriptManager.RegisterScriptDescriptors()
во время этап Render, который вызывает вышеприведенное исключение из-за того, что элемент управления не был зарегистрирован на этапе PreRender.
Кто-нибудь нашел исправление или обходной путь для этого?
Кажется, это быть огромным ограничением в WebForms, где вы не можете эффективно использовать как asyn c задачи, так и элементы управления расширением на одной странице.
Ниже приведен пример веб-страницы, иллюстрирующей эту проблему.
<%@ 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>