Проблема AjaxControlToolkit на страницах Asyn c WebForms - PullRequest
0 голосов
/ 10 февраля 2020

Существует проблема с расширителями 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().

После некоторого анализа вот что вызывает это.

  1. Базовый класс ExtenderControl, который все подклассы расширителей AjaxControlToolkit, вызывают ScriptManager.RegisterExtenderControl() в своем методе OnPreRender. Кроме того, ScriptManager сгенерирует исключение, если RegisterExtenderControl() вызывается на любом этапе, кроме PreRender.
  2. Для элементов управления, которые не видны на этапе PreRender, метод OnPreRender вызываться не будет, и, следовательно, Управление расширением не будет зарегистрировано.
  3. Страницы WebForms запускают все асинхронные c задачи после этапа PreRender и до этапа Render. Таким образом, если вы сделаете свой расширитель видимым в асинхронной задаче c, то он не будет виден еще на этапе PreRender и только на этапе рендеринга.
  4. Наконец, элементы управления расширителем вызывают 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>

1 Ответ

0 голосов
/ 11 февраля 2020

На основе предложений, опубликованных по этому вопросу, здесь https://forums.asp.net/p/2163988/6293999.aspx?p=True&t=637169211245961059 и здесь https://github.com/DevExpress/AjaxControlToolkit/issues/523, я нашел общий c способ обойти эту проблему.

По сути, ваша страница будет отслеживать элементы управления, которые имеют расширители и могут изменять их видимость при выполнении в асинхронной задаче c. Затем эти элементы управления будут временно видны в нужное время в PreRender, чтобы избежать ошибки, а затем будут скрыты по мере необходимости после завершения PreRender. Ключевым моментом здесь является использование нового метода SetControlVisible страницы для установки видимости элемента управления.

Полный исходный код этого обходного пути размещен здесь: https://github.com/Xomega-Net/XomegaFramework/blob/master/src/Xomega.Framework.Web/Views/WebPage.cs

...