예외가 발생한 위치를 파악하는 데 도움이되지 않을 수도 있지만 요청 및 쿼리 문자열에서 URL을 작성/재구성하는 방법에 대한 예제를 제공 할 수 있습니다.
레코드 목록을 표시하는 화면이 있습니다. 그것들이 많이 있기 때문에 나는 필터링과 페이지 매김을 지원할 필요가있다. 필터는 검색어 문자열로 배치됩니다 (예 : ?foo1=bar1&foo2=bar2
). 페이지 매김은 추가 페이지 크기와 현재 페이지 번호를 URL에도 넣습니다 (즉, size=15&page=1
). 대신 GetDisplayUri()
를 사용
, 내가 현재 URL을 소요 UrlHelperExtensions
가 해당 URL 쿼리 문자열을 검토하고 URL로 필요에 따라 추가 쿼리 문자열 (페이지 크기 & 현재 페이지)를 추가합니다. 페이지 매김을하기 위해
namespace DL.SO.Project.Framework.Mvc.Extensions
{
public static class UrlHelperExtensions
{
public static string Current(this IUrlHelper url, object routeValues)
{
// Get current route data
var currentRouteData = url.ActionContext.RouteData.Values;
// Get current route query string and add them back to the new route
// so that I can preserve them.
// For example, if the user applies filters, the url should have
// query strings '?foo1=bar1&foo2=bar2'. When you construct the
// pagination links, you don't want to take away those query
// strings.
var currentQuery = url.ActionContext.HttpContext.Request.Query;
foreach (var param in currentQuery)
{
currentRouteData[param.Key] = param.Value;
}
// Convert new route values to a dictionary
var newRouteData = new RouteValueDictionary(routeValues);
// Merge new route data
foreach (var item in newRouteData)
{
currentRouteData[item.Key] = item.Value;
}
return url.RouteUrl(currentRouteData);
}
}
}
, 나는 현재 페이지 크기를 추적 전체 항목, 현재 페이지, 전체 페이지의 계산, 페이지와 마지막 페이지를 시작해야합니다. 그 클래스를 만들려면, Pager.cs
.
namespace DL.SO.Project.Framework.Mvc.Paginations
{
public class Pager
{
public int TotalItems { get; private set; }
public int CurrentPage { get; private set; }
public int CurrentPageSize { get; private set; }
public int TotalPages { get; private set; }
public int StartPage { get; private set; }
public int EndPage { get; private set; }
public Pager(int totalItems, int currentPage = 1, int currentPageSize = 15)
{
currentPageSize = currentPageSize < 15
? 15
: currentPageSize;
// Calculate total, start and end pages
var totalPages = (int)Math.Ceiling(
(decimal)totalItems/(decimal)currentPageSize
);
currentPage = currentPage < 1
? 1
: currentPage;
// Only display +- 2
var startPage = currentPage - 2;
var endPage = currentPage + 2;
if (startPage <= 0)
{
endPage = endPage - startPage + 1;
startPage = 1;
}
if (endPage > totalPages)
{
endPage = totalPages;
if (endPage > 5)
{
startPage = endPage - 4;
}
}
this.TotalItems = totalItems;
this.CurrentPage = currentPage;
this.CurrentPageSize = currentPageSize;
this.TotalPages = totalPages;
this.StartPage = startPage;
this.EndPage = endPage;
}
}
}
마지막으로 나는 호출기를 구성하는 부분보기에 URL을 확장하고 Pager
클래스를 사용할 수 있습니다.
@model DL.SO.Project.Framework.Mvc.Paginations.Pager
@{
var showingRangeFrom = (Model.CurrentPage - 1) * Model.CurrentPageSize + 1;
var showingRangeTo = Model.CurrentPage * Model.CurrentPageSize;
if (showingRangeFrom > Model.TotalItems)
{
showingRangeFrom = Model.TotalItems;
}
if (showingRangeTo > Model.TotalItems)
{
showingRangeTo = Model.TotalItems;
}
}
@if (Model != null && Model.TotalItems > 0)
{
<div class="list-pager">
<div class="list-pager-info">
<span>Showing <strong>@[email protected]</strong>
of <strong>@Model.TotalItems</strong> entries
</span>
</div>
<div class="list-pagination">
<ul class="pagination">
<li class="page-item @(Model.CurrentPage == 1? "disabled" : "")">
<!-- use Url extension here -->
<a href="@Url.Current(new { page = Model.CurrentPage - 1 })"
class="page-link" tabindex="-1">
< Prev
</a>
</li>
@for (int i = Model.StartPage; i <= Model.EndPage; i++)
{
<li class="page-item @(i == Model.CurrentPage? "active" : "")">
<!-- use Url extension here -->
<a href="@Url.Current(new { page = i })"
class="page-link">@i</a>
</li>
}
<li class="page-item @(Model.CurrentPage >= Model.EndPage? "disabled" : "")">
<!-- use Url extension here -->
<a href="@Url.Current(new { page = Model.CurrentPage + 1 })"
class="page-link" tabindex="-1">Next ></a>
</li>
</ul>
</div>
</div>
}
매김에있는 링크가 함께 쿼리 문자열로 현재 URL뿐만 아니라 페이지 크기 및 현재 페이지에 반영이 방법.
이것은 훌륭한 정보이며 도움을 주셔서 감사합니다. GetDislpayUri()를 호출하는 메서드에 대한 단위 테스트를 작성 중이며 실제로 구현을 변경할 수있는 권한이 없으므로 여기서이 메서드를 실제로 사용할 수는 없습니다. – Tom
아, 알겠습니다. .NET Core는 오픈 소스이기 때문에 구현을 들여다 볼 수 있습니까? https://github.com/aspnet/HttpAbstractions/blob/dev/src/Microsoft.AspNetCore.Http.Extensions/UriHelper.cs –
아, 확장 방법이 오픈 소스라는 단서가 없었습니다. 몇 시간 전에 좋았을 텐데. 어쨌든 고마워! – Tom