14.01.2009

Пейджинг в GridView с использованием get параметров

Пейджинг в GridView, как известно, производится с помощью параметров, сохраняемых во ViewState, таким образом при каждом обновлении делается POST-запрос.

Это создает некоторые трудности. В частности, в ссылке не содержится информация о текущей странице, т.е. ее не имеет смысла кому-то передавать. Кроме того при обновлении браузер будет спрашивать передавать ли данные заново на сервер, что раздражает пользователей.

Естественное решение проблемы - использование GET-параметров. В них можно передавать номер страницы и количество элементов на странице.

Создаем класс-наследник GridView


public class ContentList : GridView
{
}


Сделаем 2 публичных свойства чтоб манипулировать GET-параметрами (чтоб избежать возможных конфликтов)


public string PageParamName
{
get { return pageParamName; }
set
{
if ( string.Equals(pageSizeParamName, value,
StringComparison.CurrentCultureIgnoreCase) )
throw new ArgumentException("parameter names are equal");
pageParamName = value;
}
}
public string PageSizeParamName
{
get { return pageSizeParamName; }
set
{
if (string.Equals(pageParamName, value,
StringComparison.CurrentCultureIgnoreCase))
throw new ArgumentException("parameter names are equal");
pageSizeParamName = value;
}
}

private string pageParamName = "page"; //default values
private string pageSizeParamName = "pagesize";


Здесь учитываем возможную ошибку, если пользователь попробует установить одинаковые значения параметров.

Теперь перекрываем метод OnInit, в котором устанавливаем значение размера страницы и номера страницы. Здесь нужно учесть что в C# нумерация массивов начинается с нуля а нам желательно начинать нумерацию с единицы.

В итоге получим


protected override void OnInit(EventArgs e)
{
base.OnInit(e);

if (! string.IsNullOrEmpty(Context.Request.QueryString[PageSizeParamName]))
{
PageSize = Int32.Parse(Context.Request.QueryString[PageSizeParamName]);
}

if (!string.IsNullOrEmpty(Context.Request.QueryString[PageParamName]))
PageIndex = Int32.Parse(Context.Request.QueryString[PageParamName]) - 1;
}


Таким образом данные берутся из GET-параметров. При желании можно проверять, является ли параметр числом и, если не является, игнорировать его. Сделать это несложно.

Остается последний шаг - перекрыть метод InitializePager и там создать ссылки с нужными GET-параметрами. Подробно описывать его не буду, приведу лишь код функции создающей GET-URL с учетом параметров пейджинга.


private string createPagedPath(int page, int pagesize)
{
string param = string.Empty;

foreach ( string s in Context.Request.QueryString.AllKeys )
{
if (string.Equals(s, PageParamName,
StringComparison.CurrentCultureIgnoreCase) )
continue;
if (string.Equals(s, PageSizeParamName,
StringComparison.CurrentCultureIgnoreCase))
continue;
param += string.Format("&{0}={1}", s, Context.Request.QueryString[s]);
}

return string.Format("{0}?{1}={2}&{3}={4}{5}",
Context.Request.Path, PageParamName, page, PageSizeParamName, pagesize, param);
}

Как видно из кода, проверяем все GET-параметры и копируем из них только те, которые не относятся к нашим параметрам с именами PageParamName и PageSizeParamName. Затем берем Path запроса, добавляем к нему параметры пейджинга и исходные параметры, если таковые имеются в запросе.

P.S. Стоит обратить внимание на изменение свойств PageParamName и PageSizeParamName, желательно прописывать их прямо на странице .aspx и не изменять в коде, поскольку это может привести к труднолокализуемым ошибкам (либо вообще не менять, а оставить значения по умолчанию).

09.01.2009

sql management studio 2008

Установил себе наконец sql server 2008 (пока что express with advanced services).
Обнаружил, что наконец-то появился более-менее приличный intellisence в редактировании хранимых процедур.
Как и следовало в общем ожидать, радость продлилась недолго. Например, в нем не поддерживаются временные таблицы.
То есть код

INSERT * FROM table INTO #temp

и далее

SELECT * FROM #temp

вызывает ошибку unknown identifier #temp. Естественно, процедура компилируется. Так что хорошее начало но работать им видимо придется еще.