我的 Web 界面有一個內置在 Razor Pages 中的控制面板,顯示管理員可以配置的各種設備,顯示在一個帶有各種按鈕的表格中,用于快速操作和資訊(如顯示啟用和連接狀態的切換)。
我最初構建它的方式它沒有分頁,以及一個帶有表單列的簡單回圈,用于快速操作,基于相對行
@{
ViewBag.BaseLayout = "/Views/Shared/_Layout_Areas.cshtml";
Layout = "/Views/Shared/_Layout_IPageable.cshtml";
}
@* other code bla bla bla *@
@foreach (var device in @Model.Devices)
{
<tr>
<td class="forms-inline">
<form id="entrydelete" method="post" onsubmit="return _formconfirm();">
<button class="btn btn-danger btn-sm" type="submit" asp-page-handler="delete" asp-route-id="@device.Id">
<i class="bi bi-trash3"></i>
</button>
</form>
<form id="useredit" method="post">
<button class="btn btn-warning btn-sm d-inline" type="submit" asp-page-handler="update" asp-route-id="@device.Id">
<i class="bi bi-pencil-square"></i>
</button>
</form>
<form id="toggle" method="post" target="_self">
<button class="btn @(device.Enabled ? "btn-success" : "btn-secondary" ) btn-sm d-inline" type="submit" asp-page-handler="toggleEnabled" asp-route-id="@device.Id">
@if (device.Enabled)
{
<i class="bi bi-toggle-on"></i>
}
else
{
<i class="bi bi-toggle-off"></i>
}
</button>
</form>
</td>
<td>@Html.Label("Description",device.Description ?? "---")</td>
<td class="font-monospace w-space-pre">@Html.Label("Ip",device.Ip)</td>
<td class="font-monospace">@Html.Label("Port",device.Port.ToString())</td>
<td>@Html.Label("Organization",device.OwnedBy?.Name)</td>
<!-- etc. etc. -->
</tr>
}
現在,如果您沒有分頁之類的東西,這會很好用……但是后來隨著設備的成倍增長,分頁解決方案需要實作。
所以我添加了一個IPageable介面并實作了擴展方法和東西,但是我添加了一個額外的布局Layout_IPageable.cshtml在經典頁面底部添加了分頁控制元件,以實作
[<-] [1] ... [n-1] [n] [n 1] ... [nmax] [->]
跨多個頁面的可重用性和樣式一致性,但我將它做成了一個表單特定頁面的常規過濾 _Layout_IPageable.cshtml
@model IPageable
@{
Layout = ViewBag.BaseLayout ?? "/Views/Shared/_Layout.cshtml";
}
<!-- render body and styles and stuff -->
<div class="paging form text-end">
<label asp-for="Paging.PageNumber" class="form-label"></label>
@if (Model.Paging.PageNumber > 1)
{
<button class="btn btn-sm btn-secondary" onclick="navigatePaging(-1)"><i class="bi bi-arrow-left"></i></button>
}
else
{
<button class="btn btn-sm btn-outline-secondary" disabled><i class="bi bi-arrow-left"></i></button>
}
<!-- etc. etc. -->
[ <input asp-for="Paging.PageNumber" style="width: min-content" form="search" min="1" max="@Model.Paging.MaxPageCount" onchange="this.form.submit()" />
/@Html.Label(Model.Paging.MaxPageCount.ToString()) ]
<!-- etc. etc. -->
<label asp-for="Paging.Take" class="form-label"></label>
<select asp-for="Paging.Take" form="search" onchange="this.form.submit()">
<option>10</option>
<option>25</option>
<option>40</option>
<option>100</option>
</select>
</div>
interface IPageable
{
DataPagingModel Paging { get; set; }
}
public static class PagingExtensions
{
public static IEnumerable<T> Page<T>( this IEnumerable<T> input, DataPagingModel paging )
{
paging.ResultsCount = input.Count();
paging.MaxPageCount = (input.Count()-1) / paging.Take 1;
paging.PageNumber = Math.Min(paging.PageNumber, paging.MaxPageCount);
return input
.Skip(paging.Skip)
.Take(paging.Take);
}
}
[ValidateAntiForgeryToken]
public partial class DevicesModel : PageModel, IPageable
{
[BindProperty(SupportsGet = true)]
public DataPagingModel Paging { get; set; }
public IActionResult OnGet()
{
thid.Devices = this._devicesSrvc
.VariusChainedLinqMethods()
.Page(this.Paging);
return this.Page();
}
public async Task<IActionResult> OnPostUpdate( Guid id )
{
/* code to update and stuff ... */
// the problem is here, in non-get methods i cannot figure out
// how to return the correct paging because this.Paging is null!
return this.OnGet();
}
/* etc. etc. */
}
問題是,現在提交以前的“快速操作”表單時,顯然沒有提交分頁表單,并且分頁重置為默認值(因此頁面 0,具有默認頁面大小且沒有過濾器)。
我該怎么辦?
將之前的“快速操作”表單實作為 ??API 呼叫,然后重新加載頁面?還是有更優雅的解決方案?
uj5u.com熱心網友回復:
解決方案實際上非常簡單,因為原始查詢是由瀏覽Referer器在提交任何表單時作為 HTTP 標頭中的 URL 發送的。
因此,在發送“發布”表單之一時,我希望參考者是該頁面的原始 GET 查詢。
鑒于它不是完全依賴的東西,而是在 variusPost處理程式結束時回傳它......
protected IActionResult RedirectReferOrReload( )
{
var referer = this.Request.Headers.Referer.SingleOrDefault();
if (string.IsNullOrEmpty(referer))
return this.RedirectToPage();
// this ensures the referer cannot go to a malicius link
return this.Redirect(this.Request.Path.Value new Uri(referer).Query);
}
public async Task<IActionResult> OnPostUpdate( Guid id )
{
/* code to update and stuff ... */
return this.RedirectReferOrReload();
}
...如果標題存在,將重定向到參考頁面,否則只需重新加載頁面。然后使用正確的查詢重新加載頁面時,顯示專案的狀態將正確更新。
現在,這對我的情況非常有用,因為我希望此頁面的目標用戶提供默認瀏覽器配置,以便Referer始終在表單上發送標題(我還更新了 ASP.NET 以指定 a Referrer-Policy)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/522451.html
標籤:C#形式asp.net 核心剃刀
