.NET Core 7迁移后RazorPage.Model.get返回空引用异常排查
问题
将ASP.NET Core 3.1项目中的州与地方政府联动下拉框功能迁移至.NET Core 7后失效,抛出以下异常:
System.NullReferenceException: 'Object reference not set to an instance of an object
Microsoft.AspNetCore.Mvc.Razor.RazorPage.Model.get returned null.
SQL表无空列,已用JSON+Ajax实现交互,且已安装Microsoft.AspNetCore.Mvc.NewtonsoftJson包,相关代码如下:
模型类
public class BiodataVM { public BiodataVM() { this.SteteCodes = new List<SelectListItem>(); this.LocalCodes = new List<SelectListItem>(); } public List<SelectListItem> SteteCodes { get; set; } public List<SelectListItem> LocalCodes { get; set; } public int LId { get; set; } public int SId { get; set; } }
视图代码
<form asp-action="Create"> <select id="statecode" asp-for="SId" class="form-control"> <option value="">--请选择--</option> @foreach (var item in ViewBag.Statelist) { <option value="@item.Value">@item.Text</option> } </select> <select id="localcode" asp-for="LId" asp-items="Model.LocalCodes" class="form-control"> <option value="">--请选择--</option> </select> </form> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <script type="text/javascript"> $(function () { $("select").each(function () { if ($(this).find("option").length <= 1) { $(this).attr("disabled", "disabled"); } }); $("select").change(function () { var value = 0; if ($(this).val() != "") { value = $(this).val(); } var id = $(this).attr("id"); $.ajax({ type: "POST", url: "/Biodata/AjaxMethod", data: { value: value, type: id }, success: function (response) { switch (id) { case "statecode": DisableDropDown("#localcode"); PopulateDropDown("#localcode", response.LocalCodes); break; } }, failure: function (response) { alert(response.responseText); }, error: function (response) { alert(response.responseText); } }); }); if ($("#statecode").val() != "" && $("#localcode").val() != "") { var message = "StateCode: " + $("#statecode option:selected").text(); message += "\nLocalCode: " + $("#localcode option:selected").text(); alert(message); } }); function DisableDropDown(dropDownId) { $(dropDownId).attr("disabled", "disabled"); $(dropDownId).empty().append('<option selected="selected" value="">--请选择--</option>'); } function PopulateDropDown(dropDownId, list) { if (list != null && list.length > 0) { $(dropDownId).removeAttr("disabled"); $.each(list, function () { $(dropDownId).append($("<option></option>").val(this['Value']).html(this['Text'])); }); } } </script>
ActionResult代码
BiodataVM model = new BiodataVM { SteteCodes = (from a in this._context.State select new SelectListItem { Value = a.SId.ToString(), Text = a.State }).ToList(), }; ViewBag.Statelist = model.SteteCodes;
JsonResult代码
public JsonResult AjaxMethod(string type, int value) { BiodataVM model = new BiodataVM(); switch (type) { case "statecode": model.LocalCodes = (from z in this._context.LocalGovt where z.SId == value select new SelectListItem { Value = z.LId.ToString(), Text = z.LocalGovt }).ToList(); break; } return Json(model); }
问题原因及解决办法
核心问题
视图中使用了Model.LocalCodes,但返回视图的Action里没有将实例化的BiodataVM模型传递给视图,导致Razor页面的Model属性为null,触发空引用异常。ASP.NET Core 3.1的兼容特性可能掩盖了这个问题,.NET 7对模型绑定的检查更严格,所以报错暴露了问题。
解决步骤
- 修改返回视图的Action,传递模型
public IActionResult Create() { BiodataVM model = new BiodataVM { SteteCodes = (from a in this._context.State select new SelectListItem { Value = a.SId.ToString(), Text = a.State }).ToList(), }; ViewBag.Statelist = model.SteteCodes; // 关键:将model传递给视图 return View(model); }
- 可选优化:用模型属性替代ViewBag
既然BiodataVM已定义SteteCodes,可以直接在视图中遍历模型属性,减少对ViewBag的依赖:
<select id="statecode" asp-for="SId" class="form-control"> <option value="">--请选择--</option> @foreach (var item in Model.SteteCodes) { <option value="@item.Value">@item.Text</option> } </select>
- 验证NewtonsoftJson配置
确保在Program.cs中正确配置NewtonsoftJson(若需替代默认的System.Text.Json):
builder.Services.AddControllersWithViews() .AddNewtonsoftJson(options => { options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; });
内容的提问来源于stack exchange,提问作者dausa
相关产品推荐
相关产品推荐

