В этом уроке мы рассмотрим, как создать простой органайзер изображений, который позволяет пользователям переупорядочивать серии изображений; эта функция может быть полезна на любом типе сайтов с изображениями, где у пользователей есть коллекция изображений, которые они загрузили или иным образом добавили в свой профиль или учетную запись. Мы будем использовать .net для извлечения и сохранения порядка изображений в базе данных SQL на сервере, а также пользовательский интерфейс jQuery для переупорядочения изображений на клиенте.
Начиная
Страница, которую мы создадим, будет иметь тип aspx ; при необходимости мы можем создавать и редактировать эти файлы с помощью простого текстового редактора, но гораздо эффективнее использовать правильную .Net IDE. Visual Web Developer Express от Microsoft — это отличная среда .Net IDE, и она абсолютно бесплатна; возьмите копию прямо сейчас с http://www.microsoft.com/express/Web/ . Его можно загрузить как часть веб-платформы; вы можете выбрать различные продукты при загрузке, для целей данного руководства мы будем использовать следующие компоненты:
- Visual Web Developer Express 2008
- SQL Server Express 2008 (с SQL Server 2008 Management Studio Express)
Веб-платформа на самом деле довольно хороша и дает вам доступ к широкому спектру популярных веб-приложений и сред, таких как dotNetNuke, Joomla, Umbraco и многих других, а установщик платформы загружает и настраивает все, что вам нужно. Загрузка и установка займет некоторое время, поэтому, пока он работает, мы можем создать область разработки; создайте новую папку и назовите ее image_organiser , затем внутри этой папки создайте две новые папки и назовите их js и css .
Вам также следует взять копию последней версии пользовательского интерфейса jQuery; Перейдите к сборщику загрузок по адресу http://jqueryui.com/download и убедитесь, что следующие компоненты в левой части страницы проверены:
- ядро
- Виджет
- мышь
- Сортируемый
Тема не требуется, но убедитесь, что версия 1.8 выбрана в правой части страницы, а затем нажмите кнопку загрузки. После загрузки архива откройте его и скопируйте следующие файлы из папки js в архиве в папку js, которую мы только что создали:
- JQuery-1.4.2.min.js
- JQuery-UI-1.8.custom.min.js
Мы также используем отличную утилиту JSON Дуга Крокфорда, которую можно скачать с http://www.JSON.org/json2.js . Сохраните копию этого файла в нашей папке js и обязательно удалите предупреждение из верхней части файла.
После завершения установки платформы запустите Visual Web Developer Express и перейдите в « Файл » Открыть веб-сайт, а затем выберите папку проекта image_organiser, которую мы только что создали. Вы получите запрос на обновление сайта до версии .net 3.5; выберите Да .
Создание базы данных
Мы создадим новую базу данных и таблицу для этого примера; откройте SQL Server Management Studio и подключитесь к локальному экземпляру SQL Server (он будет называться что-то вроде COMPUTERNAME \ SQLEXPRESS ). Чтобы создать новую базу данных, щелкните правой кнопкой мыши папку « Базы данных » и выберите « Новая база данных» . В появившемся диалоговом окне установите для имени базы данных значение image_organiser и нажмите кнопку « ОК» . Затем вы должны увидеть новую базу данных, указанную в левой панели менеджера.
Теперь нам нужно создать новую таблицу в нашей новой базе данных; разверните новую базу данных, затем щелкните правой кнопкой мыши папку « Таблицы » и выберите « Новая таблица» . Консоль управления предоставит вам пару дополнительных панелей; один показывает столбцы таблицы и один показывает свойства таблицы. Добавьте три столбца в таблицу, первый должен иметь имя src и иметь тип varchar (50) , второй должен иметь имя alt, а также тип varchar (50) . Последний столбец называется [order] и имеет тип int . Только столбец alt должен разрешать нулевые значения.
Нажмите значок диска на панели инструментов и выберите название изображения . При развертывании папки « Таблицы » в Обозревателе объектов слева должна появиться новая таблица. В полной реализации каждый пользователь приложения будет иметь свой собственный набор изображений, и, несомненно, в базе данных будут другие таблицы имен пользователей и паролей, а также другая информация, связанная с пользователем. Для целей данного учебного пособия представьте, что мы являемся единственным аутентифицированным пользователем, который манипулирует нашим собственным набором изображений.
Теперь нам нужно заполнить таблицу некоторыми данными; щелкните правой кнопкой мыши по новой таблице и выберите « Редактировать лучшие 200 строк» ; консоль снова изменится, так что у вас будет редактируемое представление таблицы. Столбец id вставляется в таблицу автоматически; в этом примере я просто использовал нулевой индекс для значений в этом столбце, но это должно совпадать с именами файлов используемых изображений. Используйте данные, показанные здесь:
Файл aspx
Чтобы создать новую страницу aspx, щелкните правой кнопкой мыши корень сайта в обозревателе решений справа от приложения и выберите Добавить новый элемент . В появившемся диалоговом окне выберите « Веб-форма» в верхней части и Visual C # в поле «Выбор языка» . Нажмите Добавить .
Это даст новую страницу с именем Default.aspx , которая автоматически откроется в IDE. Новая страница отображается в обозревателе решений справа, рядом с ней находится значок плюса, указывающий на то, что она содержит что-то. Для тех из вас, кто никогда ранее не работал с .Net, он содержит файл code-behind aspx.cs, который мы можем использовать для добавления серверной логики для страницы чуть позже.
В файле aspx уже будет несколько элементов, включая <form> ; добавьте следующий код в элемент <form> :
1
2
3
4
5
6
7
|
<div id=»outerWrap»>
<div id=»left»>
<h1>Image Organiser</h1>
<p>Re-order the images by dragging an image to a new location.
</div>
<div id=»images»></div>
</div>
|
У нас есть простой внешний контейнер с двумя элементами <div> внутри; один содержит несколько кратких инструкций, а другой будет использоваться для хранения сортируемых элементов изображения. Чтобы заполнить контейнер изображений изображениями из базы данных, мы можем использовать удобный элемент управления .Net Repeater; добавьте следующий код в контейнер изображений:
<asp: Repeater id = "imageRepeat" runat = "server"> <ItemTemplate> <li id = "<% # DataBinder.Eval (Container.DataItem," id ")%>"> <img src = "<% # DataBinder.Eval (Container.DataItem," src ")%>" alt = "<% # DataBinder.Eval (Container.DataItem," alt ")%>" /> </ Li> </ ItemTemplate> </ Жерех: Repeater>
Мы используем элемент <asp: Repeater>, элемент управления которого мы только что добавили на страницу. Когда вы откроете файл Default.aspx.cs, вы увидите, что в этом файле уже есть несколько элементов; В верхней части файла есть ряд директив использования, которые указывают серверу пространства имен компонентов .Net, которые требуются для файла aspx. Помимо включенных в файл, нам также необходимо добавить следующее:
используя System.Data; using System.Data.SqlClient;
После этого у нас есть определение класса и обработчик события Page_Load, который мы можем использовать для выполнения кода на стороне сервера при загрузке страницы aspx. В этом обработчике событий добавьте следующий код:
// определить соединение SqlConnection dbCon = new SqlConnection ("Сервер = DESKTOP \\ SQLEXPRESS; UID = sa; PWD = your_password; База данных = image_organiser"); // определить строку запроса sSQL = "Выбрать * из изображений"; // определить команду SqlCommand cmd = new SqlCommand (sSQL, dbCon); // открываем соединение dbCon.Open (); // читать данные SqlDataReader ds = cmd.ExecuteReader (); // привязка к повторителю imageRepeat.DataSource = ds; imageRepeat.DataBind (); // закрываем соединение dbCon.Close ();
Код очень прост, давайте пройдемся по нему; мы определяем новый SqlConnection, используя переменную dbCon . Значением этой переменной является строка подключения, которую мы используем для подключения к базе данных, и она состоит из имени сервера, имени пользователя (по умолчанию sa ), пароля и имени базы данных. Не забудьте заменить your_password в приведенном выше коде паролем, который вы установили при установке SQL.
Далее мы определяем наш запрос, который в данном случае просто выбирает все в базе данных, используя подстановочный знак * . Мы также храним SqlCommand в переменной, которая состоит из запроса и соединения. После этого мы можем открыть соединение с помощью метода Open () и прочитать данные в переменную SqlDataReader с помощью метода ExecuteReader (), вызванного в SqlCommand .
Наконец, мы привязываем данные к нашему элементу управления ретранслятором, устанавливая переменную ds в качестве источника данных ретранслятора и вызывая для нее метод DataBind () , прежде чем окончательно закрыть соединение с базой данных. Нам не нужно выбирать элемент управления повторителем, мы можем просто обратиться к нему напрямую, используя идентификатор, указанный на странице aspx. Первый этап нашего кода завершен, повторитель будет отображать <li> и <img> для каждой строки нашей базы данных. Однако на данный момент это будет выглядеть немного мягко, поэтому давайте добавим немного базовых стилей.
Стилизация страницы
Чтобы добавить новую таблицу стилей на сайт, щелкните правой кнопкой мыши папку css в Solution Explorer справа и выберите Add New Item ; выберите Таблицу стилей в верхней части диалогового окна и установите для поля Имя значение image_organiser.css , затем нажмите Добавить . Новый файл автоматически откроется в IDE; добавьте в него следующий код:
01
02
03
04
05
06
07
08
09
10
11
|
#outerWrap { width:1004px;
#outerWrap:after { content:».»;
h1 { font:italic normal 24px Georgia, Serif;
p { margin:0;
#left { width:218px;
#images { margin:0;
#images li { list-style-type:none;
#images .vacant { border:3px dotted #66d164;
.success, .failure { margin:0 0 0 10px;
.success { background:url(‘../img/tick.png’) no-repeat 0 1px;
.failure { background:url(‘../img/cross.png’) no-repeat 0 0;
|
Эти базовые стили просто выкладывают страницу в формате, который мы хотим для этого примера. Здесь нет ничего действительно важного, его можно легко изменить в соответствии с другими требованиями. Не забудьте добавить ссылку на новую таблицу стилей в <head> страницы со следующим:
<link rel = "stylesheet" type = "text / css" href = "css / image_organiser.css" />
На этом этапе страница должна выглядеть следующим образом при первой загрузке в браузере:
Чтобы просмотреть страницу, щелкните правой кнопкой мыши файл aspx в обозревателе решений и выберите « Просмотр в браузере» . Для отображения страницы будет использоваться встроенный веб-сервер IDE.
Делаем изображения сортируемыми
Смысл страницы состоит в том, чтобы сделать изображения сортируемыми, чтобы пользователь мог их переупорядочить, для этого нам нужно связать файлы jQuery UI в нашей папке js; добавьте следующие теги <script> непосредственно перед закрывающим тегом </ body> :
1
2
|
<script type=»text/javascript» src=»js/jquery-1.4.2.js»></script>
<script type=»text/javascript» src=»js/jquery-ui-1.8.custom.min.js»></script>
|
Сделать изображения сортируемыми чрезвычайно легко; после вышеуказанных элементов <script> добавьте следующий код:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
<script type=»text/javascript»>
$(function() {
//make li sortable
$(«#images»).sortable({
placeholder: «vacant»,
update: function(e, ui) {
//code to save new order
}
});
});
</script>
|
Все, что мы делаем, это вызываем метод sortable () для контейнера элементов, которые мы хотим отсортировать. Мы предоставляем объект конфигурации методу, определяющему имя класса, которое должно быть применено к пустому слоту, в который сортируемый элемент может быть помещен с помощью опции placeholder , и функции обратного вызова, которая должна выполняться всякий раз, когда происходит сортировка, и порядка предметы меняются. Когда мы запустим страницу в этот момент, мы обнаружим, что изображения можно сортировать и применены наши свободные стили:
Сохранение Нового Порядка
Все, что нам теперь нужно сделать в основном файле .aspx, — это отправлять новый порядок изображений на сервер всякий раз, когда изображения сортируются; замените комментарий в обратном вызове обновления следующим кодом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
//create vars
var orderArray = [], wrap = {};
//reset ‘saved’ message
$(«.success», $(«#left»)).remove();
//process each image
$(«#images img»).each(function(i) {
//build img object
var imgObj = {
«id»: $(this).parent().attr(«id»).split(«_»)[1],
«order»: i + 1
};
//add object to array
orderArray.push(imgObj);
});
//wrap in object
wrap.d = orderArray;
//pass to server
$.ajax({
type: «POST»,
url: «WebService.asmx/updateOrder»,
data: JSON.stringify(wrap),
contentType: «application/json; charset=utf-8»,
success: function(data) {
if (data.d === «saved») {
$(«<p>»).text(«New order saved!»)
.addClass(«success»).appendTo(«#left»);
} else {
$(«<p>»).text(«Save failed»)
.addClass(«failure»).appendTo(«#left»);
}
}
});
|
Давайте посмотрим, что делает этот код; сначала мы создаем пару переменных, которые нам понадобятся позже в скрипте, первая — литерал массива, вторая — литерал объекта. Затем мы удаляем все сообщения об успехах, которые могут присутствовать в предыдущих взаимодействиях сортировки. Затем мы обрабатываем каждое из изображений в сетке изображений с помощью метода each () jQuery, который будет выполнять анонимную функцию, которую мы указали один раз для каждого изображения в списке. Эта функция автоматически получает индекс для текущего элемента, который нам нужно использовать.
В этой функции мы создаем новый литерал объекта и присваиваем ему два свойства; идентификатор текущего изображения и порядковый номер текущей каждой () итерации. Затем мы вставляем этот объект в массив, который мы создали минуту назад. Как только мы сделаем это для каждого изображения на странице, мы вставим массив в обертывающий объект. Этот объект будет передан на сервер, что делается с помощью низкоуровневого метода jQuery ajax () .
Нам нужно использовать метод ajax () вместо, скажем, методов post () или getJSON () , потому что нам нужно указать contentType, чтобы сервер правильно обрабатывал данные. Мы устанавливаем тип запроса POST , определяем файл на стороне сервера с именем метода, который будет обрабатывать запрос в качестве параметра строки запроса. Мы также передаем наш подготовленный объект обтекания. Чтобы полностью преобразовать объект в синтаксис JSON, мы используем метод stringify () файла json2.js .
Мы также указываем обработчик успеха, который будет выполнен после завершения запроса; мы можем увидеть строку, возвращаемую сервером, получая доступ к данным, переданным обратно в этот обработчик успеха. Фактическая строка будет содержаться в свойстве объекта данных с меткой d . Данные, возвращаемые на страницу через AJAX в .Net, обычно доступны через объект d таким способом.
Мы можем добавить на страницу другое сообщение и имя класса в зависимости от того, указывает ли сервер на успешный или неудачный запрос. Вы можете проверить это и увидеть различные сообщения, используя Firebug, чтобы изменить атрибут id одного из контейнеров изображений на значение, которого нет в базе данных, а затем отсортировать изображение. Вот как должны выглядеть наши сообщения:
Файл метода активного сервера
Чтобы получить объект JSON, переданный на сервер через AJAX после взаимодействия сортировки, мы можем использовать файл asmx; щелкните правой кнопкой мыши корневой каталог сайта в обозревателе решений и выберите « Добавить новый элемент» . В появившемся диалоговом окне выберите « Веб-служба» в верхней части и Visual C # в поле «Выбор языка» , затем нажмите « Добавить» .
Это даст вам новый файл WebService.asmx на вашем сайте, но код для этого файла попадет в автоматически созданную папку с именем App_code . Нам вообще не нужно обновлять файл asmx, все будет сделано в файле code-behind WebService.asmx.cs . Откройте его, и вы увидите, что в файле уже много кода; измените его так, чтобы файл полностью выглядел следующим образом:
используя Систему; using System.Collections.Generic; используя System.Data; using System.Data.SqlClient; использование System.Linq; использование System.Web; использование System.Web.Services; использование System.Web.Script.Services; /// <summary> /// Получает и сохраняет новый порядок изображений /// </ summary> [WebServiceBinding (ConformsTo = WsiProfiles.BasicProfile1_1)] // Чтобы разрешить вызов этой веб-службы из сценария с использованием ASP.NET AJAX, раскомментируйте следующую строку. [System.Web.Script.Services.ScriptService] открытый класс WebService: System.Web.Services.WebService { открытый класс ImageDTO { публичная строка id {get; устанавливать; } public int order {get; устанавливать; } } [WebMethod] открытая строка updateOrder (список <ImageDTO> d) { // определить соединение SqlConnection dbCon = new SqlConnection ("Сервер = DESKTOP \\ SQLEXPRESS; UID = sa; PWD = ваш_пароль; База данных = image_organiser"); // обрабатываем объект JSON foreach (ImageDTO img в d) { // определить процедуру string sSQL = "Обновить изображения set [order] =" + img.order + ", где id =" + img.id; пытаться { // открываем соединение dbCon.Open (); // обновить данные cmd.ExecuteNonQuery (); // закрыть соединение dbCon.Close (); } catch (SqlException ex) { вернуть «не удалось»; } } // успех! возврат "сохранен"; } }
Нам нужно добавить несколько пространств имен в раздел using в верхней части файла, чтобы работать с нашей базой данных SQL. Нам также необходимо убедиться, что мы раскомментируем строку, которая позволяет нашему веб-сервису вызываться из скрипта на главной странице aspx (он явно помечен комментарием в версии файла по умолчанию).
В классе WebService нам нужно добавить новый класс, который представляет каждый из внутренних объектов в массиве, передаваемом веб-службе. Мы делаем это с помощью класса ImageDTO и присваиваем каждому объекту идентификатор и свойства заказа, а также назначаем методы getter и setter для работы со значениями этих свойств.
Далее идет метод, который вызывается из нашего скрипта; веб-метод updateOrder . Этот метод получает объект d, который мы приводим как список объектов ImageDTO ; тогда мы сможем использовать методы, определенные в нашем классе, для доступа к каждому свойству.
Мы определяем информацию о соединении, необходимую для подключения к нашей базе данных, а затем обрабатываем каждый объект в нашем списке ImageDTO . Мы извлекаем новый порядок и идентификатор изображения и используем его для обновления столбца заказа для соответствующей строки в таблице MSSQL.
Этот код относительно похож на код, который мы использовали для получения информации из базы данных при загрузке страницы, мы просто используем другую строку подключения и используем метод ExecuteNonQuery ( ) вместо ExecuteReader (), потому что мы обновляем базу данных вместо просто читаю из него. Мы также оборачиваем выполнение нашего соединения в оператор try … catch и выводим строку с ошибкой или сохраняем в зависимости от того, успешно ли выполнено обновление.
Резюме
В этом уроке мы использовали аромат .Net c. В сочетании с пользовательским интерфейсом jQuery, чтобы создать страницу, которая запоминает порядок изображений на ней и позволяет переупорядочивать изображения в соответствии с прихотями и желаниями посетителя на странице. В этом примере это простая страница, но не забывайте, что в правильной реализации это, вероятно, будет доступно только аутентифицированному пользователю; каждый пользователь будет иметь доступ к своим собственным изображениям и сможет их сортировать, а изображения будут зафиксированы в общедоступной версии страницы.
Мы не делали никакой очистки данных, передаваемых в файл на стороне сервера, который обновляет базу данных; хотя пользователь не вводит данные в текстовое поле, можно легко манипулировать исходящим запросом со страницы, чтобы отправить вредоносный код на сервер. Опасность такого рода атак будет ограничена, поскольку мы, вероятно, разрешим сортировку в первую очередь только зарегистрированным аутентифицированным пользователям. Хотя безопасность выходит за рамки данного руководства, она всегда должна быть основной задачей при работе с живым кодом.