首页 > 解决方案 > 即使操作成功,面对对象引用也未设置异常

问题描述

每次尝试输入新课程时,我都会收到以下错误。


你调用的对象是空的。AspNetCore._Views_Admin_Manage_cshtml+<b__23_12>d.MoveNext() 在 Manage.cshtml,第 34 行


这是我的控制器:

using ASP_Project.Data;
using ASP_Project.Models;
using ASP_Project.Services.Interfaces;
using ASP_Project.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace ASP_Project.Controllers
{
    public class AdminController : Controller
    {
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly SchoolContext _schoolContext;
        private readonly IAdminRepository _adminRepos;
        private readonly ITeacherRepository _teacherRepository;

        public AdminController(UserManager<ApplicationUser> userManager,
            SchoolContext schoolContext,
            IAdminRepository adminRepos,
            ITeacherRepository teacherRepository
            )
        {
            _userManager = userManager;
            _schoolContext = schoolContext;
            _adminRepos = adminRepos;
            _teacherRepository = teacherRepository;
        }

        [HttpGet]
        [Authorize(Roles = "Admin")]
        public async Task<IActionResult> Index()
        {
            ClaimsPrincipal currentUser = User;
            var user = await _userManager.GetUserAsync(currentUser);
            var admin = _adminRepos.GetAdminByUser(user);

            return View(new AdminViewModel()
            {
                FirstName = admin.FirstName,
                LastName = admin.LastName,
                MiddleName = admin.MiddleName
            });
        }

        [HttpGet]
        public IActionResult Manage()
        {
            IEnumerable<string> teachers = _teacherRepository.TeacherNames();
            return View(new CourseViewModel()
            {
                Teachers = teachers
            });
        }

        [HttpPost]
        public async Task<IActionResult> Manage(CourseViewModel courseViewModel)
        {
            var teacher = _schoolContext.Teacher.Single(t => t.FirstName == courseViewModel.TeacherName);
            Course course = new Course()
            {
                CodeID = courseViewModel.CodeID,
                Name = courseViewModel.Name,
                NumOfCredits = courseViewModel.NumOfCredits,
                TeacherID = teacher.TeacherID
            };
            await _schoolContext.Course.AddAsync(course);
            if (await _schoolContext.SaveChangesAsync() == 0)
                return RedirectToAction("Index", "Admin");
            return View(courseViewModel);
          }
       }
  }

这是我的观点:

@model ASP_Project.ViewModels.CourseViewModel
@{
    ViewData["Title"] = "Manage";
}

<h2>Manage</h2>

<div class="row">
    <div class="col-md-4">
        <form asp-controller="Admin" asp-action="Manage" method="post" class="form-horizontal" role="form">
            <h4>Create a new Course.</h4>
            <hr />
            <div asp-validation-summary="All" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="CodeID"></label>
                <input asp-for="CodeID" class="form-control" />
                <span asp-validation-for="CodeID" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Name"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="NumOfCredits"></label>
                <input asp-for="NumOfCredits" class="form-control" />
                <span asp-validation-for="NumOfCredits" class="text-danger"></span>
            </div>
            <div>
                <label asp-for="TeacherName" class="col-md-2 control-label"></label>
                <div class="col-md-10">
                    <select asp-for="TeacherName" class="form-control" required>
                        <option value="" disabled selected>Select Teacher</option>
                        @foreach (var teach in Model.Teachers)
                        {
                            <option value="@teach"> @teach </option>
                        }
                    </select>
                    <span asp-validation-for="TeacherName" class="text-danger"></span>
                </div>
            </div>

            <button type="submit" class="btn btn-default">Add</button>
        </form>
    </div>
</div>
@section Scripts {
    @await Html.PartialAsync("_ValidationScriptsPartial")
}

我的课程视图模型:

using ASP_Project.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace ASP_Project.ViewModels
{
    public class CourseViewModel
    {
        [Required]
        public string CodeID { get; set; }
        [Required]
        public int NumOfCredits { get; set; }
        [Required]
        public string Name { get; set; }
        [Required]
        public string TeacherName { get; set; }
        public IEnumerable<string> Teachers { get; set; } 
    }
}

最后是用于检索教师姓名的函数:

public IEnumerable<string> TeacherNames() => _schoolContext.Teacher.Select(t => t.FirstName);

我从异常中了解到的是,foreach 的一部分需要等待,或者其中一个对象没有被定义。

请注意,该操作仍在成功完成其工作,并且正在将数据添加到数据库中,只是这个奇怪的异常不断出现。编辑:即使@NoCodeFound answer指出我应该调试(这就是我为找到答案所做的)但我还是打算这样做,而且我碰巧发现了真正的原因。

标签: c#asp.net-mvcasp.net-core-2.0razor-pages

解决方案


结果我在 POST 后从 Manage 操作返回时搞砸了,因为我使用了:

if (await _schoolContext.SaveChangesAsync() == 0)
   return RedirectToAction("Index", "Admin");
return View(courseViewModel);

这让我再次浏览 courseViewModel,而不是被重定向到我需要的页面。所以解决方法就是:

if (await _schoolContext.SaveChangesAsync() == 0)
                return View(courseViewModel);
return RedirectToAction("Index", "Admin");

推荐阅读