Пример использования плагина jQuery Cookie или сохраняем текст поиска между запросами в приложении ASP.NET

Недавно в одном веб-приложении ASP.NET WebForms понадобился функционал сохранения строки поиска между запросами, т.е. чтобы текст между запросами оставался на месте между отправками страниц. Возможность не критически важная на самом деле, но что поделать, раз заказчик захотел. Подобная функционал ничего сложного из себя не представляет и есть много способов её решения . Сегодня я продемонстрирую одно, из таких решений, на мой всгляд очень красивое, для того чтобы показать как маленький плагин jQuery Cookie может облегчить работу с куками на клиенте. Как обычно создадим стандарное приложение ASP.NET WebForms (можно и MVC, суть задачи от этого не меняется) которое предлагает нам Visual Studio 2010 по умолчанию. Добавим в файл разметки Site.Master кнопку, текстовое поле и скрипт.
<%@ Master Language="C#" AutoEventWireup="true" 
CodeBehind="Site.master.cs" Inherits="WebSearch.SiteMaster" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 
Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
    <title></title>
    <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" />
    <script src="<%=ResolveUrl("~/Scripts/jquery-1.8.2.min.js")%>" 
    type="text/javascript"></script>
    <script src="<%=ResolveUrl("~/Scripts/jquery-ui-1.8.24.min.js")%>" 
    type="text/javascript"></script>
    <script src="<%=ResolveUrl("~/Scripts/jquery.cookie.min.js")%>" 
    type="text/javascript"></script>
    <asp:ContentPlaceHolder ID="HeadContent" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form runat="server">
    <div class="page">
        <div class="header">
            <div class="title">
                <h1>
                    My ASP.NET Application
                </h1>
            </div>
            <div class="loginDisplay">
            <asp:TextBox ID="SearchText" runat="server" 
            ClientIDMode="Static"></asp:TextBox>
            <asp:Button ID="SearchButton" runat="server" Text="Поиск" />
                <asp:LoginView ID="HeadLoginView" runat="server" EnableViewState="false">
                    <AnonymousTemplate>
                        [ <a href="~/Account/Login.aspx" ID="HeadLoginStatus" 
                        runat="server">Log In</a> ]
                    </AnonymousTemplate>
                    <LoggedInTemplate>
                        Welcome <span class="bold"><asp:LoginName ID="HeadLoginName" 
                        runat="server" /></span>!
                        [ <asp:LoginStatus ID="HeadLoginStatus" 
                        runat="server" LogoutAction="Redirect" LogoutText="Log Out"
                        LogoutPageUrl="~/"/> ]
                    </LoggedInTemplate>
                </asp:LoginView>
            </div>
            <div class="clear hideSkiplink">
                <asp:Menu ID="NavigationMenu" runat="server" CssClass="menu" 
                EnableViewState="false" IncludeStyleBlock="false" Orientation="Horizontal">
                    <Items>
                        <asp:MenuItem NavigateUrl="~/Default.aspx" Text="Home"/>
                        <asp:MenuItem NavigateUrl="~/About.aspx" Text="About"/>
                    </Items>
                </asp:Menu>
            </div>
        </div>
        <div class="main">
            <asp:ContentPlaceHolder ID="MainContent" runat="server"/>
        </div>
        <div class="clear">
        </div>
    </div>
    <div class="footer">
    </div>
    </form>
    <script type="text/javascript">
      $(document).ready(function () {
      //Читаем значение cookie в строку поиска.
        $("#SearchText").attr('value', $.cookie('SearchData'));
        //Перед любой GET/POST отправкой, поле потеряет фокус
        //и данные запишутся в cookie.
        $("#SearchText").focusout(function () {
          var searchText = $(this).val();
          /*Если используется несколько параметров,
          чтобы иметь возможность заполнить серверную коллекцию
          типа ключ - значение, можно поступить так.
          //var cookieValue = $.param({ Key1: searchText });
          Можно и другие ключи добавлять, если критерий
          поиска не один, обычно так и бывает.*/
          
          var cookieValue = searchText;

          /*Отключаем кодирование текста в куках,
          иначе придётся декодировать их на сервере.
          //$.cookie.raw = true;
          Данная возможнось важна, если нужно отправлять пары 
          ключ-значение, чтобы коллекция Request.Cookies["SearchData"].Values
          автоматически могла распознать их.*/
          
          //Записываем данные.
          $.cookie('SearchData', cookieValue, { path: '/' });
        });
      });
    </script>
</body>
</html>
Важно последовательно подключить нужные скрипты. Версия плагина 1.3, которая используется тут и взята отсюда. В момент написания статьи можно было установить версию 1.0 через пакетный менеджер NuGet. Как показано в коде, установка куки занимает одну строчку, вместо многих строк, которые мы должны были писать самостоятельно. Остался добавит последний кусок кода:
namespace WebSearch
{
  public partial class SiteMaster : System.Web.UI.MasterPage
  {
    protected void Page_Load(object sender, EventArgs e)
    {
      if (Request.Cookies["SearchData"] != null)
      {
        //Можно использовать ключи для доступа к данным,
        //если нужно сохранять критерии поиска
        //но в данном случае работа с куками производится исключительно на клиенте,
        //и сохраняем только саму стоку.
        //SearchText.Text = Request.Cookies["SearchData"].Values["Key1"].ToString();
      }
      else
      {
        HttpCookie cookie = new HttpCookie("SearchData");
        cookie.Path = "/";
        //Добавляем параметры, но в данном примере они не нужны.
        //cookie.Values["Key1"] = String.Empty;
        //Можно и второй и ещё больше ключей добавить.
        //cookie.Values["Key2"] = String.Empty;
        Response.Cookies.Add(cookie);
      }
    }
  }
}

Получим примерно следующий функционал.



Текст поиска, набранный в последний раз, останется на месте между отправками страницы, если конечно куки пользователь не отключил. Можно было поступить по другому, используя например ViewState или Session. Но основной целью была демонстрация того, как плагин jQuery Cookie инкапсулирует рутинный код, который должны были писать для разбора значений. Мелочи, но приятные.