Обновление серверных элементов управления ASP.NET с использованием ajax - PullRequest
1 голос
/ 28 октября 2010

Этот вопрос заставил меня задуматься о том, как можно решить проблему относительно невыполнимой задачи: плавную интеграцию сгенерированного сервером HTML-кода из ASP.NET с управлением на стороне клиента с помощью javascript.Конечно, вы всегда можете использовать javascript / jquery / library для создания одинакового отображения на стороне клиента.Но в большинстве случаев проще выполнять весь рендеринг на сервере, а не просто передавать данные клиентскому элементу управления, который должен обрабатывать пользовательский интерфейс и рендеринг.Или, может быть, у вас уже есть много менее интерактивного серверного кода, который вы на самом деле не хотите полностью повторять, используя библиотеки javascript, чтобы просто добавить лучшую интерактивность.

У меня была теория, которая, кажется, работаетв основном доказательство концепции.Предположим, вы хотите полностью перерисовать HTML-код сгенерированного сервером элемента управления на основе события на стороне клиента, без повторной отправки.Итак, используя jquery, у меня есть страница:

    default.aspx:
   <a id="link1" href="#">Click Here</a>
   <div id="container">
   <asp:PlaceHolder id="MyPlaceholder" runat="server" />
   </div>
    <script type="text/javascript">
        $(document).ready(function() {
            $('#link1').click(function() {
                $.ajax({
                    url: "default.aspx",
                    type: "GET",
                    dataType: "html",
                    async: true,
                    data: { "ajax": "1" },
                    success: function(obj) {
                    // replace the HTML
                        $('#container').html(obj);
                    }
                });
            });
        });

Событие заставляет его запрашивать себя с помощью ajax.Код, который выполняет хитрость, выглядит следующим образом:

    TestUserControl ctl;
    string ajax;
    protected void Page_Load(object sender, EventArgs e)
    {
        ctl = (TestUserControl)Page.LoadControl("TestUserControl.ascx");
        Myplaceholder.Controls.Add(ctl);
        ctl.OnRender += new TestuserControl.RenderHandler(ctl_Render);
    }
    protected void Page_PreRender()
    {
        ajax = Request.QueryString["ajax"] == null ? "" : Request.QueryString["ajax"];
    }
    void ctl_Render()
    {
        if (ajax == "1")
        {
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);

            using (HtmlTextWriter writer = new HtmlTextWriter(sw))
            {
                ctl.DoRender(writer);
            }

            Response.Write(sb.ToString());
            Response.End();
        }
    }

В TestUserControl я раскрываю base.render для получения вывода:

   public void DoRender(HtmlTextWriter writer)
    {
        base.Render(writer);
    }

В основном, если страница вызывается безСтрока запроса "ajax", она действует как сама.Но когда эта строка запроса используется, она перехватывает выходной поток из содержимого, которое меня интересует (usercontrol с именем TestUserControl.ascx), и отображает только этот .Это возвращается клиенту, который обновляет HTML.Все идентификаторы будут воссозданы точно так же, как и раньше, поскольку я не пытаюсь отображать только этот элемент управления изолированно, а в контексте его собственной страницы.Теоретически каждый бит магии, созданный ASP.NET, должен воспроизводиться, извлекаться и обновляться с помощью ajax-запроса.

Помимо очевидной неэффективности, кажется, что в этом небольшом тесте он работает слаженно.Я могу полностью перерисовать элемент управления, используя сгенерированный сервером HTML без обратной передачи, и я написал ноль JavaScript.Этот пример на самом деле ничего не меняет, но было бы просто передать больше параметров для изменения вывода.

Мне было интересно, пробовал ли кто-нибудь подобное на практике?О каких потенциальных проблемах я мог не думать?

Если производительность сервера не является проблемой, может показаться, что это может быть довольно простым способом получить множество функциональных возможностей со всеми преимуществами серверных элементов управления ASP.NET.Но мне кажется, что я не могу найти никаких обсуждений об использовании этой техники на практике, поэтому мне интересно, чего мне не хватает.

Ответы [ 3 ]

2 голосов
/ 28 октября 2010

Ну, для начала, вы отправляете запрос GET на свою страницу, поэтому элемент управления, который вы хотите обновить, не будет получать обновленные данные формы. Что еще более важно, ViewState будет потеряно, и вы, вероятно, не хотите этого, если ваш пользовательский элемент управления не очень прост.

Вы можете обойти проблему, используя запрос POST, но есть и другие потенциальные проблемы, например, Можете ли вы гарантировать, что клиентские сценарии, встроенные в ваш пользовательский элемент управления, будут выполняться снова или нет, если вы обновляете их последовательно во всех браузерах?

К счастью, другие уже решили эти проблемы. Я бы посоветовал вам поместить пользовательский элемент управления в UpdatePanel и принудительно обновить со стороны клиента:

__doPostBack("yourUpdatePanelClientID", "");
0 голосов
/ 29 июня 2012

Хотелось бы, чтобы было больше дискуссий на тему перехода веб-форм ASP.NET в современную эпоху.Я должен был выяснить большинство всего самостоятельно.Я лично стремлюсь к самым простым решениям и избегаю всех решений, которые требуют наслоения на еще большее количество Microsoft.Ничего не имею против MS, я просто хочу сохранить простоту и использовать обычные веб-стандарты.

До сих пор я был в состоянии AJAX записать все, что я пробовал, используя загрузку jQuery.Простых ответов нет, но если вы настойчивы, вы, вероятно, сможете решить любую проблему на стороне клиента, возникающую в результате использования устаревших методов ASP.NET.

Я думаю, что самое важное, что нужно сделать, это прекратить использование ViewState.Полностью.Это заставит вас отказаться от множества ужасных практик, которые могут вызвать проблемы на клиенте.Это на самом деле проще, чем вы думаете.И в этот момент вещи AJAXing обычно просто работают.Даже DataGrids.Сделайте свою собственную подкачку страниц, на стороне клиента или на сервере, это не так сложно, и тогда вы сможете использовать свое решение везде.

Проблемы будут исходить от сторонних материалов, которые вы не можете контролировать.В этих случаях вы можете использовать инструменты разработчика IE (F12), чтобы увидеть, что ASP.NET изначально отправлял.В худшем случае, вам придется вычеркнуть немного JavaScript и запустить его самостоятельно.На практике мне редко приходится делать что-либо такое ужасное.Я полагаю, если вы используете много тяжелых контролей веса, это было бы нецелесообразно, но в этом случае вы уже купили ферму.

0 голосов
/ 05 ноября 2010

Если альтернатива использует UpdatePanel, определенно стоит рассмотреть частичный рендеринг.Даже если вы обновляете только небольшую часть страницы с помощью UpdatePanel, эти обновления должны отправлять весь ViewState обратно на сервер, сервер должен запустить всю страницу в течение ее жизненного цикла , визуализируйте его, а затем извлеките частичную область.Вы получаете значительный удар по производительности за его удобство.

В вашем случае вы по-прежнему испытываете удар по жизненному циклу страницы, так как визуализируете этот частичный элемент в паре ASPX.Это не так плохо, как UpdatePanel, но не нужно.

Я обнаружил, что разбиение частичного рендеринга на веб-сервис или обработчик HttpHandler работает хорошо.Это намного быстрее, чем большинство других методов рендеринга частичек в WebForms, но все же допускает гибкость использования пользовательских элементов управления для шаблонов.

Недостатком является то, что элементы управления внутри пользовательского элемента управления не могут обрабатывать PostBacks.Вы, безусловно, можете повторно отрендерить его и / или передать параметры для управления его рендерингом, но вы не можете использовать его для рендеринга GridView и ожидать, что его пейджинговые ссылки будут работать, например.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...