Pagination mit ASP.NET MVC 4

Pagination mit ASP.NET MVC 4

Pagination mit ASP.NET MVC 4

Hin und wieder kann es vorkommen, dass man in einer Web-Anwendung eine Liste mit sehr vielen Items anzeigen will. Dies kann jedoch schnell zum Ärgernis werden, wenn man mehrere hunderte, wenn nicht sogar tausende Einträge hat, die dargestellt werden müssen.
Um dieses Problem zu lösen, zeigt man nur einen Teilbereich dieser Einträge an und lässt den Benutzer, mit Hilfe von Paginierung, den gewünschten Bereich finden.

Im Falle von ASP.NET MVC 4 gibt es jedoch nicht von Haus aus ein solches Hilfsmittel und muss sich dieses selber erstellen. Damit man das Paging für jeden Controller neu erzeugen muss und in der Razor View nutzen kann, benötigt man einen eigenen HtmlHelper und eine PagingInfo Klasse, mit der man identifizieren kann, wieviele Items eine Liste hat und wo sich der Benutzer gerade befindet.

Die PagingInfo Klasse enhält die Anzahl der Items in der gesamten Liste, die Anzahl Items, die pro Seite angezeigt werden sollen, die Seitennummer, auf der suich der Benutzer aktuell befindet und ein Property, das mit Hilfe der Anzahl Items und Items pro Seite berechnet, wieviele Seiten es für diese Liste gibt.

public class PagingInfo
{
	public int TotalItems { get; set; }
	public int ItemsPerPage { get; set; }
	public int CurrentPage { get; set; }

	public int TotalPages
	{
		get { return (int) Math.Ceiling((decimal) TotalItems/ItemsPerPage); }
	}
}

Die HtmlExtension soll mit Hilfe der PagingInfo Klasse ermitteln, wie viele Links (<a> Tags) erzeugt werden müssen und einer Delegation für die korrekten Verweise (dem href-Attribut) und sieht dann sieht folgendermaßen aus:

public static MvcHtmlString PageLinks(this HtmlHelper html, PagingInfo pagingInfo, Func pageUrl,
									  object htmlAttributes = null)
{
	var result = new StringBuilder();

	// Für jede Seite soll ein eigener Link erzeugt werden
	for (var i = 1; i <= pagingInfo.TotalPages; i++)
	{
		// i is gleich der Seitennummer und wird für die Anzeige genutzt
		var tag = new TagBuilder("a") {InnerHtml = i.ToString(CultureInfo.InvariantCulture)};
		
		// wenn die Seitennummer gleich der aktuellen Seite des Benutzers ist, wird eine CSS Klasse hinzugefügt
		if (i == pagingInfo.CurrentPage)
		{
			tag.AddCssClass("selected");
		}
		
		// Die folgenden Zeilen dienen der Vervollständigung und erlauben somit zusätzliche HTML Attribute an
		// die einzelnen Links hinzuzufügen, wie man es von den üblichen HtmlHelpern auch gewohnt ist.
		if (htmlAttributes != null)
		{
			var newAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
			tag.MergeAttributes(newAttributes);
		}
		tag.MergeAttribute("href", pageUrl(i));
		result.Append(tag.ToString());
	}
	// Der erzeugte HtmlString wird hier zurückgeliefert
	return MvcHtmlString.Create(result.ToString());
}

Wenn wir nun einen Controller haben, auf dem eine lange Liste angezeigt werden soll, bedienen wir uns einem ViewModel, welches die Liste der anzuzeigenden Items und die PagingInfo Klasse hält.

public class ValueListViewModel
{
	public IEnumerable Values { get; set; }
	public PagingInfo PagingInfo { get; set; }
}

Im Controller übergeben wir dem ViewModel die Liste der Werte und erzeugen für die PagingInfo eine neue Klasse. Der Parameter „page“ wird genutzt, um die vom Benutzer gewählte Seite zu identifizieren.

public ActionResult List(int page = 1)
{
	var pageSize = 10;
	var model = new ValueListViewModel
		{
			// Liste der Items
			Values = _valuesRepository
				.OrderBy(v => v)
				// nicht benötigte Items überspringen
				.Skip((page - 1) * pageSize)
				// nimm nur soviele, wie angezeigt werden sollen
				.Take(pageSize),
				// PagingInfo Klasse
				PagingInfo = new PagingInfo
					 {
						 CurrentPage = page,
						 ItemsPerPage = pageSize,
						 TotalItems = _valuesRepository.Count()
					 }
		};
	return View(model);
}

Die RazorView könnte nun folgendermaßen aussehen:

@model AjaxDialogs.Models.ValueListViewModel

List

@foreach (var item in Model.Values) {}

Value
@item
@* Pagination Links mit Hilfe des erzeugten HtmlHelpers generieren lassen *@ @* Die Delegation erzeugt dabei für jeden <a> Tag den Link /Controller/List&page=x, wobei x die Seitennummer darstellt *@ @Html.PageLinks(Model.PagingInfo, x => Url.Action(„List“, new { page = x }))

Nun kann man mit Hilfe der PagingInfo Klasse, einem recht einfachem ViewModel und dem HtmlHelper überall die Pagination nutzen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload the CAPTCHA.