所以我遇到了一个问题,我希望这是一个愚蠢的问题。我有以下课程 ViewStudents.cshtml.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using HogwartsRegistry.Data;
using HogwartsRegistry.Models;
using HogwartsRegistry.Models.ViewModels;
using HogwartsRegistry.Utility;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
namespace HogwartsRegistry.Pages.Instructors
{
public class ViewStudentsModel : PageModel
{
private readonly ApplicationDbContext _db;
public ViewStudentsModel(ApplicationDbContext db)
{
_db = db;
}
[BindProperty]
public InstructorViewStudentsViewModel InstrViewVM { get; set; }
public void OnGet(int classId)
{
var ClaimsIdentity = (ClaimsIdentity)User.Identity;
var claim = ClaimsIdentity.FindFirst(ClaimTypes.NameIdentifier);
string instructorId = claim.Value;
InstrViewVM = new InstructorViewStudentsViewModel()
{
Class = _db.Classes.FirstOrDefault(i => i.Id == classId),
};
// Get a list of people enrolled in the current class
InstrViewVM.Students = _db.StudentClasses
.Include(s => s.Student)
.Include(s => s.Class.Course)
.Where(s => s.ClassId == classId)
.ToList();
// Get the studentIds of everyone enrolled in the class
List<string> studentIds = InstrViewVM.Students.Select(s => s.StudentId).ToList();
InstrViewVM.otherStudents = _db.Students
.Where(s => !studentIds.Contains(s.Id))
.ToList();
var count = InstrViewVM.otherStudents.Count;
StringBuilder param = new StringBuilder();
param.Append("/Students?studentPage=:");
InstrViewVM.PagingInfo = new PagingInfo()
{
CurrentPage = 1,
ItemsPerPage = SD.PaginationUserPageSize,
TotalItems = count,
UrlParameters = param.ToString()
};
InstrViewVM.otherStudents = InstrViewVM.otherStudents
.OrderBy(u => u.LastName)
.Skip((1 - 1) * SD.PaginationUserPageSize)
.Take(InstrViewVM.PagingInfo.ItemsPerPage).ToList();
}
public void OnGetSearch(int studentPage = 1, string searchLastName = null, string searchYear = null, string searchHouse = null)
{
StringBuilder param = new StringBuilder();
param.Append("/Students?studentPage=:");
if (searchLastName != null)
{
param.Append("&searchLastName=");
param.Append(searchLastName);
InstrViewVM.otherStudents = InstrViewVM.otherStudents.Where(s => s.LastName == searchLastName).ToList();
}
if (searchYear != null)
{
param.Append("&searchYear=");
param.Append(searchYear);
InstrViewVM.otherStudents = InstrViewVM.otherStudents.Where(s => s.Year == Convert.ToInt32(searchYear)).ToList();
}
if (searchHouse != null)
{
param.Append("&searchHouse=");
param.Append(searchHouse);
InstrViewVM.otherStudents = InstrViewVM.otherStudents.Where(s => s.House == searchHouse).ToList();
}
}
public async Task<IActionResult> OnPostUnenrollStudent(int studentClassId)
{
StudentClasses classEntry = await _db.StudentClasses.FindAsync(studentClassId);
_db.StudentClasses.Remove(classEntry);
await _db.SaveChangesAsync();
return Page();
}
public async Task<IActionResult> OnPostEnroll(string studentId)
{
if (ModelState.IsValid)
{
StudentClasses enrollment = new StudentClasses();
enrollment.StudentId = studentId;
enrollment.ClassId = InstrViewVM.Class.Id;
_db.StudentClasses.Add(enrollment);
await _db.SaveChangesAsync();
}
return Page();
}
}
}
以及随附的HTML:
@page
@model HogwartsRegistry.Pages.Instructors.ViewStudentsModel
@{
ViewData["Title"] = "ViewStudents";
}
<div class="scratches">
<h1>View Students</h1>
@if (Model.InstrViewVM.Students.Count > 0)
{
<form method="post">
<table class="table table-striped">
<tr class="table table-secondary">
<th>@Html.DisplayNameFor(s => Model.InstrViewVM.Students[0].Id)</th>
<th>@Html.DisplayNameFor(s => Model.InstrViewVM.Students[0].Class.CRN)</th>
<th>@Html.DisplayNameFor(s => Model.InstrViewVM.Students[0].Class.Course.CourseNum)</th>
<th>@Html.DisplayNameFor(s => Model.InstrViewVM.Students[0].Class.Course.CourseTitle)</th>
<th>@Html.DisplayNameFor(s => Model.InstrViewVM.Students[0].Student.FirstName)</th>
<th>@Html.DisplayNameFor(s => Model.InstrViewVM.Students[0].Student.LastName)</th>
<th></th>
</tr>
@foreach (var stud in Model.InstrViewVM.Students)
{
<tr>
<td>@Html.DisplayFor(s => stud.Id)</td>
<td>@Html.DisplayFor(s => stud.Class.CRN)</td>
<td>@Html.DisplayFor(s => stud.Class.Course.CourseNum)</td>
<td>@Html.DisplayFor(s => stud.Class.Course.CourseTitle)</td>
<td>@Html.DisplayFor(s => stud.Student.FirstName)</td>
<td>@Html.DisplayFor(s => stud.Student.LastName)</td>
<td><button type="submit" class="btn btn-danger small" asp-page-handler="UnenrollStudent" asp-route-studentClassId="@stud.Id">Delete</button></td>
</tr>
}
</table>
</form>
}
</div>
<br />
<br />
<form method="get">
<div class="scratches">
<h3>Add a Student</h3>
<div class="border">
<div style="height: 60px;" class="container border border-secondary">
<div class="row">
<div class="col-11">
<div class="row" style="padding-top:10px">
<div class="col-4">
@Html.Editor("searchLastName", new
{
htmlAttributes = new
{
@class = "form-control",
placeholder = "Last Name..."
}
}
)
</div>
<div class="col-4">
@Html.Editor("searchYear", new
{
htmlAttributes = new
{
@class = "form-control",
placeholder = "Year..."
}
}
)
</div>
<div class="col-4">
@Html.Editor("searchHouse", new
{
htmlAttributes = new
{
@class = "form-control",
placeholder = "House..."
}
}
)
</div>
</div>
</div>
<div class="col-1">
<div class="row" style="padding-top:10px; padding-right:15px;">
<button type="submit" name="submit" class="btn btn-info form-control" value="Search" asp-page-handler="Search"><i class="fas fa-search"></i></button>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
<form method="post">
<div class="scratches">
<table class="table table-striped">
<tr class="table table-secondary">
<th>@Html.DisplayNameFor(s => Model.InstrViewVM.otherStudents[0].FirstName)</th>
<th>@Html.DisplayNameFor(s => Model.InstrViewVM.otherStudents[0].LastName)</th>
<th>@Html.DisplayNameFor(s => Model.InstrViewVM.otherStudents[0].Year)</th>
<th>@Html.DisplayNameFor(s => Model.InstrViewVM.otherStudents[0].House)</th>
<th><!-- Empty for formatting--></th>
</tr>
@foreach (var stud in Model.InstrViewVM.otherStudents)
{
<tr>
<td>@Html.DisplayFor(s => stud.FirstName)</td>
<td>@Html.DisplayFor(s => stud.LastName)</td>
<td>@Html.DisplayFor(s => stud.Year)</td>
<td>@Html.DisplayFor(s => stud.House)</td>
<td><button type="submit" class="btn btn-info" asp-page-handler="Enroll"
asp-route-studentId="@stud.Id">
<i class="fa fa-plus"></i> Enroll</button></td>
</tr>
}
<tr>
<td colspan="5" class="text-right">
<div page-model="@Model.InstrViewVM.PagingInfo" asp-action="Index" page-class="btn border"
page-class-normal="btn btn-light" page-class-selected="btn btn-info active" class="btn-group"></div>
</td>
</tr>
</table>
</div>
</form>
还有ViewModel
using System.Collections.Generic;
namespace HogwartsRegistry.Models.ViewModels
{
public class InstructorViewStudentsViewModel
{
public Class Class { get; set; }
public List<StudentClasses> Students { get; set; }
public List<Student> otherStudents { get; set; }
public PagingInfo PagingInfo { get; set; }
}
}
我遇到的问题是,在加载页面并调用OnGet(int classId)时,将填充绑定的InstrViewVM中的所有内容
但是,如果我单击任意按钮以取消注册(OnPostUnenrollStudent)或注册(OnPostEnroll)学生,我的InstrViewVM模型绑定对象突然不会实例化。当我尝试招收学生时,InstrViewVM对象为null,如下所示
当我在OnGet(classId)方法中明确实例化我的模型绑定时,我似乎无法弄清楚为什么没有实例化我的模型绑定。任何帮助,将不胜感激。让我知道是否需要提供更多信息。
答案 0 :(得分:0)
OnGet
方法仅在响应使用get
动词的HTTP请求时执行。您的按钮点击会生成post
个请求。在先前的get
请求中生成的任何状态都不会保留(因为HTTP是无状态的),因此您也需要在post
处理程序方法中重新生成模型等。
将模型实例化重构为单独的方法,然后在OnGet
和OnPost
方法中调用它可能是一个好主意。
答案 1 :(得分:0)
原因是您使用的<td>@Html.DisplayFor(s => stud.FirstName)</td>
仅呈现了具有<td>FirstNameSample</td>
属性的name
之类的值。
form标记仅发送具有属性input
的标记元素select
,textarea
,name
,...。因此,当您发布表单时,您的绑定将失败并且不向处理程序发送任何内容。您始终可以在浏览器中按F12
来检查“网络”选项卡以查看您发送的表单数据。
解决方案是您可以改用<input asp-for=" ">
:
@{int i = 0;}
@foreach (var stud in Model.InstrViewVM.Students)
{
<tr>
<td><input asp-for="@Model.InstrViewVM.Students[@i].Id" /></td>
<td><input asp-for="@Model.InstrViewVM.Students[@i].Class.CRN" /></td>
<td><input asp-for="@Model.InstrViewVM.Students[@i].Class.Course.CourseNum" /></td>
<td><input asp-for="@Model.InstrViewVM.Students[@i].Class.Course.CourseTitle" /></td>
<td><input asp-for="@Model.InstrViewVM.Students[@i].Student.FirstName" /></td>
<td><input asp-for="@Model.InstrViewVM.Students[@i].Student.LastName" /></td>
<td><button type="submit" class="btn btn-danger small" asp-page-handler="UnenrollStudent" asp-route-studentClassId="@stud.Id">Delete</button></td>
</tr>
i++;
}
或者您可以像使用@Html.EditorFor
@Html.EditorFor(model => model.InstrViewVM.Students[@i].Id, new { htmlAttributes = new { @class = "form-control", Name = "InstrViewVM.Students[" + @i + "].Id", @id = "InstrViewVM.Students[" + @i + "].Id" } })