PaginatedList onpostasync - ArgumentNullException:值不能为 null。 (参数'model')在paginnatelist上提交时
PaginatedList onpostasync - ArgumentNullException: Value cannot be null. (Parameter 'model') when submitting on paginnatelist
嗨,也许有人能给我指出正确的方向。
我使用 ms 站点上的示例创建了一个分页列表页面。
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-5.0
稍作修改。我用输入框替换了一个项目,因为我想编辑列表并进行批量保存,而不是打开新页面上的每个项目进行编辑。
但是当它点击提交按钮时我得到了错误。
ArgumentNullException:值不能为空。 (参数'model')
Microsoft.AspNetCore.Mvc.RazorPages.PageModel.TryValidateModel(对象模型,字符串名称)
如果我绑定 属性
[BindProperty(SupportsGet = true)]
public PaginatedList<CompanyDataListing> CustomersDisplayList { get; set; }
我得到跟随错误
ArgumentException: 类型 'BizFinder.PaginatedList`1[BizFinder.Data.CompanyDataListing]' 没有默认构造函数(参数 'type')
甚至分页列表也不会呈现。
我的 sumbit 代码如下。
public PaginatedList<CompanyDataListing> CustomersDisplayList { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!TryValidateModel(CustomersDisplayList, nameof(CustomersDisplayList)))
{
return Page();
}
foreach (var item in CustomersDisplayList)
{
if (item.GoogleCategory != "")
{
string cat = item.GoogleCategory;
}
}
return Page();
}
我的html如下。
@using (Html.BeginForm(FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<table class="table">
<thead>
<tr>
<th>
<a asp-page="./Index" asp-route-sortOrder="@Model.NameSort"
asp-route-currentFilter="@Model.CurrentFilter">
@Html.DisplayNameFor(model => model.CustomersDisplayList[0].CompanyName)
</a>
</th>
<th>
@Html.DisplayNameFor(model => model.CustomersDisplayList[0].Keywords)
</th>
<th>
<a asp-page="./Index" asp-route-sortOrder="@Model.DateSort"
asp-route-currentFilter="@Model.CurrentFilter">
@Html.DisplayNameFor(model => model.CustomersDisplayList[0].GoogleCategory)
</a>
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.CustomersDisplayList)
{
<tr>
<td>
<input type="hidden" asp-for="CustomersDisplayList[0].Id" />
@Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Keywords)
</td>
<td>
@*@Html.DisplayFor(modelItem => item.GoogleCategory)*@
<input asp-for="CustomersDisplayList[0].GoogleCategory" name="Category1" placeholder="Input your keyword" class="form-control GoogleCategory" autofocus="autofocus" />
<span asp-validation-for="CustomersDisplayList[0].GoogleCategory" class="text-danger"></span>
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
<div asp-validation-summary="All">
<span>Please correct the following errors</span>
</div>
@* @Html.ValidationSummary(true, "", new { @class = "text-danger" })*@
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
}
完整的代码库是
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BizFinder.Data;
using BizFinder.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
//https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-5.0
namespace BizFinder.Pages.Admin
{
public class ManCatergoryModel : PageModel
{
private readonly ApplicationDbContext _context;
private readonly IConfiguration Configuration;
private readonly IAuthorizationService _authorizationService;
public int PageSize { get; set; } = 10;
// private readonly SchoolContext _context;
public ManCatergoryModel(ApplicationDbContext context, IConfiguration configuration)
{
_context = context;
Configuration = configuration;
}
public string NameSort { get; set; }
public string DateSort { get; set; }
public string CurrentFilter { get; set; }
public string CurrentSort { get; set; }
// public IList<CompanyDataListing> CustomersDisplayList { get; set; }
// [BindProperty(SupportsGet = true)]
public PaginatedList<CompanyDataListing> CustomersDisplayList { get; set; }
public async Task OnGetAsync(string sortOrder,
string currentFilter, string searchString, int? pageIndex)
{
CurrentSort = sortOrder;
NameSort = String.IsNullOrEmpty(sortOrder) ? "CompanyName" : "";
DateSort = sortOrder == "Keywords" ? "date_desc" : "Date";
if (searchString != null)
{
pageIndex = 1;
}
else
{
searchString = currentFilter;
}
CurrentFilter = searchString;
// using System;
IQueryable<CompanyDataListing> CompData = from s in _context.CompanyDataList
where s.GoogleCategory == null
select s;
switch (sortOrder)
{
case "name_desc":
CompData = CompData.OrderByDescending(s => s.CompanyName);
break;
case "Date":
CompData = CompData.OrderBy(s => s.Keywords);
break;
case "GoogleCategory":
CompData = CompData.OrderByDescending(s => s.GoogleCategory);
break;
default:
CompData = CompData.OrderBy(s => s.CompanyName);
break;
}
// var pageSize = Configuration.GetValue("PageSize", 4);
CustomersDisplayList = await PaginatedList<CompanyDataListing>.CreateAsync(
CompData.AsNoTracking(), pageIndex ?? 1, PageSize);
}
public async Task<IActionResult> OnPostAsync(PaginatedList<CompanyDataListing> Datalist)
{
// List < CompanyDataListing > mm = CustomersDisplayList.ToList();
foreach (var item in Datalist)
{
string str = item.GoogleCategory;
}
return Page();
}
}
}
您正在 OnPost
处理程序中引用 CustomerDisplayList
,但它尚未初始化,因此出现异常。您在 OnGet 处理程序中对其进行了初始化,但仅针对 GET 请求执行。如果你想使用 POST 请求,你还需要在其中初始化 CustomerDisplayList
。
就其价值而言,您链接到的示例在整个周期中使用 GET 请求。这通常对分页和过滤结果更有意义。这样,条件将作为查询字符串值或路由数据在 URL 中传递,这意味着您可以为 filtered/paged 结果添加书签。您不需要为 GET 请求呈现防伪令牌。
首先要知道教程中的分页是后台分页。点击下一页时,每次都会重新请求数据,所以如果要批量提交,只能提交当前页数据。
如果你想批量提交当前页面的数据,那么你可以修改你的代码如下。
页面模型:
public class IndexModel : PageModel
{
private readonly PageListRazorContext _context;
private readonly IConfiguration Configuration;
public IndexModel(PageListRazorContext context, IConfiguration configuration)
{
_context = context;
Configuration = configuration;
}
public string NameSort { get; set; }
public string KeywordsSort { get; set; }
public string CurrentSort { get; set; }
public PaginatedList<CompanyDataListing> CompanyDataListing { get;set; }
public async Task OnGetAsync(string sortOrder,int? pageIndex)
{
NameSort = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
KeywordsSort = sortOrder == "Keywords" ? "keywords_desc" : "Keywords";
IQueryable<CompanyDataListing> company = from s in _context.CompanyDataListing
select s;
switch (sortOrder)
{
case "name_desc":
company = company.OrderByDescending(s => s.CompanyName);
break;
case "Keywords":
company = company.OrderBy(s => s.Keywords);
break;
case "keywords_desc":
company = company.OrderByDescending(s => s.Keywords);
break;
default:
company = company.OrderBy(s => s.CompanyName);
break;
}
var pageSize = Configuration.GetValue("PageSize", 4);
CompanyDataListing = await PaginatedList<CompanyDataListing>.CreateAsync(
company.AsNoTracking(), pageIndex ?? 1, pageSize);
}
public IActionResult OnPost(List<CompanyDataListing> Datalist)
{
//....
return RedirectToPage("./Index");
}
}
页数:
<form method="post">
<table class="table">
<thead>
<tr>
<th>
<a asp-page="./Index" asp-route-sortOrder="@Model.NameSort">
@Html.DisplayNameFor(model => model.CompanyDataListing[0].CompanyName)
</a>
</th>
<th>
<a asp-page="./Index" asp-route-sortOrder="@Model.KeywordsSort">
@Html.DisplayNameFor(model => model.CompanyDataListing[0].Keywords)
</a>
</th>
<th>
@Html.DisplayNameFor(model => model.CompanyDataListing[0].GoogleCategory)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.CompanyDataListing)
{
<tr>
<td>
<input type="hidden" asp-for="@item.CompanyName" name="Datalist[@i].CompanyName" />
@Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td>
<input type="hidden" asp-for="@item.Keywords" name="Datalist[@i].Keywords" />
@Html.DisplayFor(modelItem => item.Keywords)
</td>
<td>
<input asp-for="@item.GoogleCategory" name="Datalist[@i].GoogleCategory" placeholder="Input your keyword" class="form-control GoogleCategory" autofocus="autofocus" />
<span asp-validation-for="@item.GoogleCategory" class="text-danger"></span>
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
</td>
@{i++;}
</tr>
}
</tbody>
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
@{
var prevDisabled = !Model.CompanyDataListing.HasPreviousPage ? "disabled" : "";
var nextDisabled = !Model.CompanyDataListing.HasNextPage ? "disabled" : "";
}
<a asp-page="./Index"
asp-route-sortOrder="@Model.CurrentSort"
asp-route-pageIndex="@(Model.CompanyDataListing.PageIndex - 1)"
class="btn btn-primary @prevDisabled">
Previous
</a>
<a asp-page="./Index"
asp-route-sortOrder="@Model.CurrentSort"
asp-route-pageIndex="@(Model.CompanyDataListing.PageIndex + 1)"
class="btn btn-primary @nextDisabled">
Next
</a>
</form>
测试结果:
嗨,也许有人能给我指出正确的方向。
我使用 ms 站点上的示例创建了一个分页列表页面。 https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-5.0
稍作修改。我用输入框替换了一个项目,因为我想编辑列表并进行批量保存,而不是打开新页面上的每个项目进行编辑。 但是当它点击提交按钮时我得到了错误。
ArgumentNullException:值不能为空。 (参数'model') Microsoft.AspNetCore.Mvc.RazorPages.PageModel.TryValidateModel(对象模型,字符串名称)
如果我绑定 属性
[BindProperty(SupportsGet = true)]
public PaginatedList<CompanyDataListing> CustomersDisplayList { get; set; }
我得到跟随错误
ArgumentException: 类型 'BizFinder.PaginatedList`1[BizFinder.Data.CompanyDataListing]' 没有默认构造函数(参数 'type')
甚至分页列表也不会呈现。
我的 sumbit 代码如下。
public PaginatedList<CompanyDataListing> CustomersDisplayList { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!TryValidateModel(CustomersDisplayList, nameof(CustomersDisplayList)))
{
return Page();
}
foreach (var item in CustomersDisplayList)
{
if (item.GoogleCategory != "")
{
string cat = item.GoogleCategory;
}
}
return Page();
}
我的html如下。
@using (Html.BeginForm(FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<table class="table">
<thead>
<tr>
<th>
<a asp-page="./Index" asp-route-sortOrder="@Model.NameSort"
asp-route-currentFilter="@Model.CurrentFilter">
@Html.DisplayNameFor(model => model.CustomersDisplayList[0].CompanyName)
</a>
</th>
<th>
@Html.DisplayNameFor(model => model.CustomersDisplayList[0].Keywords)
</th>
<th>
<a asp-page="./Index" asp-route-sortOrder="@Model.DateSort"
asp-route-currentFilter="@Model.CurrentFilter">
@Html.DisplayNameFor(model => model.CustomersDisplayList[0].GoogleCategory)
</a>
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.CustomersDisplayList)
{
<tr>
<td>
<input type="hidden" asp-for="CustomersDisplayList[0].Id" />
@Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Keywords)
</td>
<td>
@*@Html.DisplayFor(modelItem => item.GoogleCategory)*@
<input asp-for="CustomersDisplayList[0].GoogleCategory" name="Category1" placeholder="Input your keyword" class="form-control GoogleCategory" autofocus="autofocus" />
<span asp-validation-for="CustomersDisplayList[0].GoogleCategory" class="text-danger"></span>
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
<div asp-validation-summary="All">
<span>Please correct the following errors</span>
</div>
@* @Html.ValidationSummary(true, "", new { @class = "text-danger" })*@
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
}
完整的代码库是
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BizFinder.Data;
using BizFinder.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
//https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-5.0
namespace BizFinder.Pages.Admin
{
public class ManCatergoryModel : PageModel
{
private readonly ApplicationDbContext _context;
private readonly IConfiguration Configuration;
private readonly IAuthorizationService _authorizationService;
public int PageSize { get; set; } = 10;
// private readonly SchoolContext _context;
public ManCatergoryModel(ApplicationDbContext context, IConfiguration configuration)
{
_context = context;
Configuration = configuration;
}
public string NameSort { get; set; }
public string DateSort { get; set; }
public string CurrentFilter { get; set; }
public string CurrentSort { get; set; }
// public IList<CompanyDataListing> CustomersDisplayList { get; set; }
// [BindProperty(SupportsGet = true)]
public PaginatedList<CompanyDataListing> CustomersDisplayList { get; set; }
public async Task OnGetAsync(string sortOrder,
string currentFilter, string searchString, int? pageIndex)
{
CurrentSort = sortOrder;
NameSort = String.IsNullOrEmpty(sortOrder) ? "CompanyName" : "";
DateSort = sortOrder == "Keywords" ? "date_desc" : "Date";
if (searchString != null)
{
pageIndex = 1;
}
else
{
searchString = currentFilter;
}
CurrentFilter = searchString;
// using System;
IQueryable<CompanyDataListing> CompData = from s in _context.CompanyDataList
where s.GoogleCategory == null
select s;
switch (sortOrder)
{
case "name_desc":
CompData = CompData.OrderByDescending(s => s.CompanyName);
break;
case "Date":
CompData = CompData.OrderBy(s => s.Keywords);
break;
case "GoogleCategory":
CompData = CompData.OrderByDescending(s => s.GoogleCategory);
break;
default:
CompData = CompData.OrderBy(s => s.CompanyName);
break;
}
// var pageSize = Configuration.GetValue("PageSize", 4);
CustomersDisplayList = await PaginatedList<CompanyDataListing>.CreateAsync(
CompData.AsNoTracking(), pageIndex ?? 1, PageSize);
}
public async Task<IActionResult> OnPostAsync(PaginatedList<CompanyDataListing> Datalist)
{
// List < CompanyDataListing > mm = CustomersDisplayList.ToList();
foreach (var item in Datalist)
{
string str = item.GoogleCategory;
}
return Page();
}
}
}
您正在 OnPost
处理程序中引用 CustomerDisplayList
,但它尚未初始化,因此出现异常。您在 OnGet 处理程序中对其进行了初始化,但仅针对 GET 请求执行。如果你想使用 POST 请求,你还需要在其中初始化 CustomerDisplayList
。
就其价值而言,您链接到的示例在整个周期中使用 GET 请求。这通常对分页和过滤结果更有意义。这样,条件将作为查询字符串值或路由数据在 URL 中传递,这意味着您可以为 filtered/paged 结果添加书签。您不需要为 GET 请求呈现防伪令牌。
首先要知道教程中的分页是后台分页。点击下一页时,每次都会重新请求数据,所以如果要批量提交,只能提交当前页数据。
如果你想批量提交当前页面的数据,那么你可以修改你的代码如下。
页面模型:
public class IndexModel : PageModel
{
private readonly PageListRazorContext _context;
private readonly IConfiguration Configuration;
public IndexModel(PageListRazorContext context, IConfiguration configuration)
{
_context = context;
Configuration = configuration;
}
public string NameSort { get; set; }
public string KeywordsSort { get; set; }
public string CurrentSort { get; set; }
public PaginatedList<CompanyDataListing> CompanyDataListing { get;set; }
public async Task OnGetAsync(string sortOrder,int? pageIndex)
{
NameSort = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
KeywordsSort = sortOrder == "Keywords" ? "keywords_desc" : "Keywords";
IQueryable<CompanyDataListing> company = from s in _context.CompanyDataListing
select s;
switch (sortOrder)
{
case "name_desc":
company = company.OrderByDescending(s => s.CompanyName);
break;
case "Keywords":
company = company.OrderBy(s => s.Keywords);
break;
case "keywords_desc":
company = company.OrderByDescending(s => s.Keywords);
break;
default:
company = company.OrderBy(s => s.CompanyName);
break;
}
var pageSize = Configuration.GetValue("PageSize", 4);
CompanyDataListing = await PaginatedList<CompanyDataListing>.CreateAsync(
company.AsNoTracking(), pageIndex ?? 1, pageSize);
}
public IActionResult OnPost(List<CompanyDataListing> Datalist)
{
//....
return RedirectToPage("./Index");
}
}
页数:
<form method="post">
<table class="table">
<thead>
<tr>
<th>
<a asp-page="./Index" asp-route-sortOrder="@Model.NameSort">
@Html.DisplayNameFor(model => model.CompanyDataListing[0].CompanyName)
</a>
</th>
<th>
<a asp-page="./Index" asp-route-sortOrder="@Model.KeywordsSort">
@Html.DisplayNameFor(model => model.CompanyDataListing[0].Keywords)
</a>
</th>
<th>
@Html.DisplayNameFor(model => model.CompanyDataListing[0].GoogleCategory)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.CompanyDataListing)
{
<tr>
<td>
<input type="hidden" asp-for="@item.CompanyName" name="Datalist[@i].CompanyName" />
@Html.DisplayFor(modelItem => item.CompanyName)
</td>
<td>
<input type="hidden" asp-for="@item.Keywords" name="Datalist[@i].Keywords" />
@Html.DisplayFor(modelItem => item.Keywords)
</td>
<td>
<input asp-for="@item.GoogleCategory" name="Datalist[@i].GoogleCategory" placeholder="Input your keyword" class="form-control GoogleCategory" autofocus="autofocus" />
<span asp-validation-for="@item.GoogleCategory" class="text-danger"></span>
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
</td>
@{i++;}
</tr>
}
</tbody>
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</div>
@{
var prevDisabled = !Model.CompanyDataListing.HasPreviousPage ? "disabled" : "";
var nextDisabled = !Model.CompanyDataListing.HasNextPage ? "disabled" : "";
}
<a asp-page="./Index"
asp-route-sortOrder="@Model.CurrentSort"
asp-route-pageIndex="@(Model.CompanyDataListing.PageIndex - 1)"
class="btn btn-primary @prevDisabled">
Previous
</a>
<a asp-page="./Index"
asp-route-sortOrder="@Model.CurrentSort"
asp-route-pageIndex="@(Model.CompanyDataListing.PageIndex + 1)"
class="btn btn-primary @nextDisabled">
Next
</a>
</form>
测试结果: