ASP.NET MVC传递Model仍报错:WebViewPage<TModel>.Model.get返回null
问题:System.Web.Mvc.WebViewPage.Model.get returned null 报错
我被这个错误困扰好几天了,确认自己已经正确传递了Model,但点击“Actualizar Usuario”按钮时,在获取用户ID的第一个标签处报错:System.Web.Mvc.WebViewPage<TModel>.Model.get returned null。
Controller方法
public ActionResult EditaUsuario(int id) { List<usuario> user = new List<usuario>(); string sql = "query..." using (SqlConnection cn = new SqlConnection(cadenaConexion)) { // ... } List<estudiante> estudiante = new List<estudiante>(); string sqlEstudiante = "query..."; using (SqlConnection cn = new SqlConnection(cadenaConexion)) { // ... } ViewModelUsuarioEstudiante viewModel = new ViewModelUsuarioEstudiante() { user = user, student = estudiante }; if (id >= 0) { if (ModelState.IsValid) { return View(viewModel); } else { } } else { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } }
Model类
namespace Cursos.Models { public class ViewModelUsuarioEstudiante { public List<usuario> user { get; set; } public List<estudiante> student { get; set; } } }
View代码
@model Cursos.Models.ViewModelUsuarioEstudiante <form action="@Url.Action("EditaUsuario", "Usuario")" method="post"> <input type="hidden" name="id" id="id" class="form-control" value="@Model.user[0].id" /> <!-- Role input --> <select class="form-select" name="rol" aria-label="Default select example" required> <option value="@Model.user[0].rol_id">@Model.user[0].roles.rol</option> <option value="ADMIN">ADMIN</option> <option value="CLIENTE">CLIENTE</option> </select> <br /> <!-- Name input --> <div class="form-outline mb-4"> <input type="text" name="nombre" id="nombre" class="form-control" value="@Model.user[0].nombre" required /> <label class="form-label" for="nombre">Nombre</label> </div> @if (Model.user[0].estudiante == true) { <div class="form-outline mb-4"> <input type="text" name="matricula" id="matricula" value="@Model.student[0].matricula" class="form-control" /> <label class="form-label" for="matricula">Matricula</label> </div> <div class="row"> <div class="col-md-8"> <!-- Name input --> <div class="form-outline mb-4"> <input type="text" name="carrera" id="carrera" value="@Model.student[0].carrera" class="form-control" /> <label class="form-label" for="carrera">Carrera o Programa</label> </div> </div> <div class="col-md-4"> <!-- Lastname input --> <select class="form-select" name="nivelEstudios" id="estudios" aria-label="Default select example"> <option value="@Model.student[0].nivelEstudios">@Model.student[0].nivelEstudios</option> <option value="TSU">TSU</option> <option value="INGENIERIA">INGENIERIA</option> </select> </div> </div> } <!-- Submit button --> <button type="submit" class="btn btn-primary btn-block mb-3">Actualizar Usuario</button> <button type="button" class="btn btn-danger btn-block mb-3">Cancelar</button> </form>
我的尝试方案
我考虑用空值判断来修复,代码如下:
<input type="hidden" name="id" id="id" class="form-control" value="@(Model.user != null && Model.user.Any() ? Model.user[0].id.ToString() : "")" />
问题原因及解决办法
核心问题
点击提交按钮后触发的是POST请求,但你的Controller里只有处理GET请求的EditaUsuario(int id)方法,没有对应的POST重载方法。当表单提交时,默认会调用同名的POST方法,而你没实现这个方法,导致MVC返回View时没有传递Model,所以Model为null,触发报错。
另外,即使有POST方法,你当前的代码还有两个潜在问题:
- 直接访问
Model.user[0],如果user集合为空,会触发索引越界错误; - Controller里的
ModelState.IsValid判断时机不对——GET请求时ModelState本来就是有效的,这个判断毫无意义。
分步解决
添加POST重载方法
在Controller中添加处理表单提交的POST方法,确保提交后能正确传递Model或重新加载数据:[HttpPost] public ActionResult EditaUsuario(int id, FormCollection form) { // 1. 处理表单提交的更新逻辑 // ...执行更新数据库的代码... // 2. 重新加载用户和学生数据(和GET方法里的逻辑一致) List<usuario> user = new List<usuario>(); string sql = "query..."; using (SqlConnection cn = new SqlConnection(cadenaConexion)) { // ...填充user数据... } List<estudiante> estudiante = new List<estudiante>(); string sqlEstudiante = "query..."; using (SqlConnection cn = new SqlConnection(cadenaConexion)) { // ...填充estudiante数据... } ViewModelUsuarioEstudiante viewModel = new ViewModelUsuarioEstudiante() { user = user, student = estudiante }; // 3. 返回View并传递Model return View(viewModel); }完善View中的空值判断
除了判断Model.user是否为空,还要判断集合是否有元素,避免索引越界:<!-- 示例:用户ID隐藏域的空值处理 --> <input type="hidden" name="id" id="id" class="form-control" value="@(Model != null && Model.user != null && Model.user.Any() ? Model.user[0].id.ToString() : "")" /> <!-- 角色下拉框的空值处理 --> <select class="form-select" name="rol" aria-label="Default select example" required> @if (Model != null && Model.user != null && Model.user.Any()) { <option value="@Model.user[0].rol_id">@Model.user[0].roles.rol</option> } <option value="ADMIN">ADMIN</option> <option value="CLIENTE">CLIENTE</option> </select>修正Controller中的无效判断
删除GET方法里多余的ModelState.IsValid判断,因为GET请求时没有提交表单数据,ModelState默认是有效的:public ActionResult EditaUsuario(int id) { // ...加载数据的代码... ViewModelUsuarioEstudiante viewModel = new ViewModelUsuarioEstudiante() { user = user, student = estudiante }; if (id >= 0) { return View(viewModel); // 直接返回View,不需要判断ModelState } else { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } }
内容的提问来源于stack exchange,提问作者CsCheems
相关产品推荐
相关产品推荐

