Как стать автором
Обновить

Использование UpdatePanel и иже с ним

Время на прочтение9 мин
Количество просмотров20K
Каждый, кто занимается веб-программированием, рано или поздно сталкивается с задачей реализации асинхронных запросов на сервер и обработкой возвращаемого результата.
Если смотреть со стороны Asp.net, то ребята из Майкрософт сделали огромную работу для того, чтобы облегчить нам всем жизнь. Однако в моей голове присутствует какая-то маниакальная идея, запрещающая использовать то, принципы работы чего я не понимаю. Таким образом, кривая дорожка завела меня в исследование работы объекта UpdatePanel и иже с ним. Прошурудив множество форумов, я обнаружил десятки изъявлений о том, что «UpdatePanel – SUCKS», подкрепленные различными разрозненными объяснениями. Но ни одно из них так и не заставило меня окончательно разубедиться в отрицательном эффекте его использования. В связи с этим, приняв на веру, что все сказанное различными Анонимусами на форумах верно, я начал рыть.
И вот до чего дошло.


1. Построение страницы без AJAX. Определение для чего нам нужен AJAX.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>Страница без Аякса</title>
</head>
<body>
  <form id="form1" runat="server">
  <div>
    <asp:Label ID="Label1" runat="server" ></asp:Label>
    <br />
    <br />
    <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
  </div>
  </form>
</body>
</html>


* This source code was highlighted with Source Code Highlighter.


protected void Button1_Click(object sender, EventArgs e)
  {
    Label1.Text = DateTime.Now.ToString();
  }

* This source code was highlighted with Source Code Highlighter.



Когда страница загружается в браузере, на ней присутствует только кнопка. При нажатии на кнопку, происходит заполнение Label’а временем.
Перед тем, как кнопка была нажата код страницы выглядит следующим образом:
<html xmlns="http://www.w3.org/1999/xhtml">

<head><title>

  Страница без Аякса

</title></head>

<body>

  <form method="post" action="Test.aspx" id="form1">

<div class="aspNetHidden">

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTE2MjY5MTY1NWRko6bmPqIZK4XzwlJ+QT95KATKkAm7XgkyNT8uG1kyAYY=" />

</div>

<div class="aspNetHidden">

  <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgKd+pPDBwKM54rGBoC4gybAW7W7f/8WUBQh0YQDD1jlQXYgaQH1TnNEFqnS" />

</div>

  <div>

    <span id="Label1">Label</span>

    <br />

    <br />

    <input type="submit" name="Button1" value="Button" id="Button1" />

  </div>

  </form>

</body>

</html>

* This source code was highlighted with Source Code Highlighter.


При нажатии на кнопку код страницы изменится следующим образом:
<html xmlns="http://www.w3.org/1999/xhtml">

<head><title>

  Страница без Аякса

</title></head>

<body>

  <form method="post" action="Test.aspx" id="form1">

<div class="aspNetHidden">

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKLTE2MjY5MTY1NQ9kFgICAw9kFgICAQ8PFgIeBFRleHQFEzA2LjA0LjIwMTEgMjI6MzM6MzBkZGSqilrbUiK+hZQi417owBVMMBY0PhVIsFIco8gKMAgDzg==" />

</div>

<div class="aspNetHidden">

  <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgLasIQ/AoznisYG8Y0mtUQQkyTrw6eGx7daZxUnrJZkgkJYAwlkImZYyNg=" />

</div>

  <div>

    <i><b><span id="Label1">06.04.2011 22:33:30</span></b></i>

    <br />

    <br />

    <input type="submit" name="Button1" value="Button" id="Button1" />

  </div>

  </form>

</body>

</html>

* This source code was highlighted with Source Code Highlighter.


Как мы видим, в целом страница осталась такой же. Немного изменился ViewState и содержание
<span id="Label1"></span>

* This source code was highlighted with Source Code Highlighter.
. При этом, для такого маленького изменения потребовалась перезагрузка всей страницы.
Вывод — не комильфо.

Построение страницы с AJAX


Добавим на страницу элементы, которые предлагает нам Visual Studio, и которые необходимы для реализации поставленной задачи: ScriptManager и UpdatePanel.

Код страницы изменится следующим образом:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>Страница с использованием Аякса</title>
</head>
<body>
  <form id="form1" runat="server">
  <div>

    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
    <ContentTemplate>
    <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
    <br />
    <br />
    <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
    </ContentTemplate>
    </asp:UpdatePanel>
    
  </div>
  </form>
</body>
</html>

* This source code was highlighted with Source Code Highlighter.


Естественно при нажатии на кнопку происходит запрос.
Используем сниффер, чтобы рассмотреть поближе, что же отправляется на сервер, при таком запросе. И что принимается с него.
Request

ScriptManager1=UpdatePanel1%7CButton1&__EVENTTARGET=&__EVENTARGUMENT=&
__VIEWSTATE=%2FwEPDwULLTEyNTU5OTE4NDBkZBeGYz2ykWCdLe%2FOqUGKO6XyNu
fetXoAHtWu%2B6HogbQM&__EVENTVALIDATION=%2FwEWAgLfxMyuBgKM54rGBm5yI89
MSG1Ab3%2FionirqDlYwJw90SrasAVtECg7kMKg&__ASYNCPOST=true&Button1=Button

Response

1|#||4|172|updatePanel|UpdatePanel1|
<span id="Label1">06.04.2011 22:45:32</span>
    <br />
    <br />
    <input type="submit" name="Button1" value="Button" id="Button1" />

|144|hiddenField|__VIEWSTATE|/wEPDwULLTEyNTU5OTE4NDAPZBYCAgMPZBYCAgMPZBY
CZg9kFgICAQ8PFgIeBFRleHQFEzA2LjA0LjIwMTEgMjI6NDU6MzJkZGSsSgFqm7m2vsFaoPo+4cjv
hIKZqpewoFXAcOyEREOqHw==|64|hiddenField|__EVENTVALIDATION|/wEWAgKhlZm1BwKM5
4rGBneyIIjYM0XM0O/oSExJWXVpXaQHZzYDddopSIBcDVj+|0|asyncPostBackControlIDs|||0|
postBackControlIDs|||26|updatePanelIDs||tUpdatePanel1,UpdatePanel1|0|
childUpdatePanelIDs|||25|panelsToRefreshIDs||UpdatePanel1,UpdatePanel1|2|
asyncPostBackTimeout||90|9|formAction||Test.aspx|18|pageTitle||Страница без Аякса|

Если рассмотреть ответ поближе, то мы увидим в нем что-то напоминающее содержимое нашего UpdatePanel и новый ViewState. И все это по размерам значительно меньше целой страницы. В принципе, мы этого и добивались. Плюс ничего не мигает. А если подумать немного, и вынести из внутренностей UpdatePanel'а кнопку, вызывающую запрос — то получается и того меньше, однако что это за ViewState. Ведь он формируется на основе всех контролов на странице, не только тех, которые обновляются асинхронно. Получается, что при использовании UpdatePanel страница проходит весь свой цикл, в независимости от того, как идет запрос: синхронно или асинхронно.

Этот факт конечно же мог стать последним гвоздем в гроб UpdatePanel. Но ребята из Майкрософт, не были бы ребятами из Майкрософта, если бы оставили все это просто так.

Все это исправляется довольно просто добавлением в программном коде следующего условия:

if (!ScriptManager1.IsInAsyncPostBack)
{
Label1.Text = "В первый раз";
}


* This source code was highlighted with Source Code Highlighter.


Данное условие необходимо добавить в обработчики этапов создания страницы.
Все что находится внутри этого условия не будет выполняться при каждой асинхронной загрузке, а все что else — будет.

Отказываемся от использования UpdatePanel


Вроде все теперь хорошо. Все довольны, но, на мой взгляд, какой-то осадок остается, да и как оно работает так и не разобрались.

Вроде кто-то где-то говорил про Веб-Сервисы…

Вот давайте тут про них и продолжим.

Добавим к нашему сайту новый WebService и раскомментируем атрибут[System.Web.Script.Services.ScriptService]

В Visual Studio 2010 в нем автоматически формируется функция:

[WebMethod]
  public string HelloWorld() {
    return "Hello World";
  }


* This source code was highlighted with Source Code Highlighter.


Не будем в ней ничего менять.

Далее нам предстоит сделать следующее:

1) объяснить странице, где сидят вебсервисы
2) создать javascript функцию, которая обращается к вебсервису
3) создать триггер этой функции

А нашу страничку изменим до такого вида:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Test" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>Страница с использованием Аякса, но без UpdatePanel</title>
</head>
<body>
  <form id="form1" runat="server">
  <div>

  <script>
    function GetResult() {
      WebService.HelloWorld(function (result) {
        $get('Label1').innerHTML = result;
      });
    }
  </script>

    <asp:ScriptManager ID="ScriptManager1" runat="server">
    <Services>
    <asp:ServiceReference Path="~/WebService.asmx" />
    </Services>
    </asp:ScriptManager>

   
    <asp:Label ID="Label1" runat="server" Text="Label" ClientIDMode="Static"></asp:Label>
    <br />
    <br />
    <input type="button" onclick="GetResult()" value="Button" />
    
   
    
  </div>
  </form>
</body>
</html>


* This source code was highlighted with Source Code Highlighter.


Если просмотреть ответ, который дал нам сервер, то он будет таким:
{«d»:«Hello World»}

Вывод: Все получилось круто.

объект xmlHttpRequest


Если окунуться еще глубже в эту тему, то все вышеуказанное работает через простой объект xmlHttpRequest. Но это уже совсем другая история.

Так, как у меня всегда были проблемы с формулированием результирующих выводов, я с официального разрешения хабраюзера Shedal пишу его слова:

Я бы сказал, что UpdatePanel действительно облегчают разработку, и, конечно же, при обмене данными с сервером получается меньший траффик, чем при полной перезагрузке страницы. Однако объем передаваемых данных все равно зачастую больше минимального необходимого. В большинстве случаев это абсолютно не критично, но иногда, при активном обмене данными с сервером, лучше использовать веб-сервисы именно как замену асинхронным постбекам.

Вообще, у веб-сервисов круг применений намного шире и причин выбрать их может быть много. Например, универсальность программного интерфейса по обмену данных с сервером в целях создания нескольких пользовательских интерфейсов (e.g., мобильного, десктопного и вебового). И даже в таком случае вполне нормально, когда веб-сервисы используются только как прослойка между бизнес-логикой и интерфейсом, а интерфейс все равно оперирует стандартными средствами ASP.NET, в т.ч. UpdatePanel'ями, используя веб-сервисы только для обмена данными.

В то же время, у UpdatePanel есть множество преимуществ, ведь они, в отличие от веб-сервисов, разрабатывались специально для асинхронного изменения HTML-кода страницы. Отсюда удобные триггеры, вложенность панелей, автоматический рендеринг (который в противном случае вам прийдется реализовывать вручную на JS), и многое другое.

и еще:

Изображение НЕЛЬЗЯ загрузить асинхронно! Только сэмулировать асинхронную загрузку.

Всем успехов!)
Теги:
Хабы:
+2
Комментарии28

Публикации

Истории

Работа

.NET разработчик
74 вакансии

Ближайшие события