You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MVC脚手架关联表创建提交时出现NullReferenceException异常

MVC CRUD实体关联提交时触发NullReferenceException异常

开发基于脚手架生成的MVC CRUD表格,配置Activo与Usuario、Procesador等实体关联后,Create页面下拉列表能正常显示关联数据,但点击Create提交时触发NullReferenceException(错误信息:Object reference not set to an instance of an object)。手动输入ID可正常提交,推测问题出在下拉列表值的获取或传递环节。

实体类代码

public class Activo
{
    public int id { get; set; }

    [Required]
    [StringLength(100)]
    public string Marca { get; set; }

    [Required]
    [StringLength(100)]
    public string Modelo { get; set; }
    [Required]
    [StringLength(100)]
    public string Tarjeta_Video { get; set; }
    public int? ID_Usuario { get; set; }
    public int? ID_Procesador { get; set; }
    public int? ID_Memoria { get; set; }
    public int? ID_DiscoDuro { get; set; }

    // Navigation properties
    [ForeignKey("ID_Usuario")]
    public virtual Usuario Usuario { get; set; }

    [ForeignKey("ID_Procesador")]
    public virtual Procesador Procesador { get; set; }

    [ForeignKey("ID_Memoria")]
    public virtual Memoria Memoria { get; set; }

    [ForeignKey("ID_DiscoDuro")]
    public virtual DiscoDuro DiscoDuro { get; set; }
}

Controller代码

// GET: Activos/Create
public IActionResult Create()
{
    ViewData["ID_DiscoDuro"] = new SelectList(_context.DiscoDuro, "id", "Marca");
    ViewData["ID_Memoria"] = new SelectList(_context.Memoria, "id", "Marca");
    ViewData["ID_Procesador"] = new SelectList(_context.Procesador, "id", "Marca");
    ViewData["ID_Usuario"] = new SelectList(_context.Usuario, "id", "ApellidoMaterno");
    return View();
}

// POST: Activos/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("id,Marca,Modelo,Tarjeta_Video,ID_Usuario,ID_Procesador,ID_Memoria,ID_DiscoDuro")] Activo activo)
{
    if (ModelState.IsValid)
    {
        _context.Add(activo);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    ViewData["ID_DiscoDuro"] = new SelectList(_context.DiscoDuro, "id", "Modelo", activo.ID_DiscoDuro);
    ViewData["ID_Memoria"] = new SelectList(_context.Memoria, "id", "Modelo", activo.ID_Memoria);
    ViewData["ID_Procesador"] = new SelectList(_context.Procesador, "id", "Modelo", activo.ID_Procesador);
    ViewData["ID_Usuario"] = new SelectList(_context.Usuario, "id", "ApellidoMaterno", activo.ID_Usuario);
    return View(activo);
}

View代码

<form asp-action="Create">
    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Marca" class="control-label"></label>
        <input asp-for="Marca" class="form-control" />
        <span asp-validation-for="Marca" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Modelo" class="control-label"></label>
        <input asp-for="Modelo" class="form-control" />
        <span asp-validation-for="Modelo" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="Tarjeta_Video" class="control-label"></label>
        <input asp-for="Tarjeta_Video" class="form-control" />
        <span asp-validation-for="Tarjeta_Video" class="text-danger"></span>
    </div>
    <div class="form-group">
        <label asp-for="ID_Usuario" class="control-label"></label>
        <select asp-for="ID_Usuario" class ="form-control" asp-items="ViewBag.ID_Usuario"></select>
    </div>
    <div class="form-group">
        <label asp-for="ID_Procesador" class="control-label"></label>
        <select asp-for="ID_Procesador" class ="form-control" asp-items="ViewBag.ID_Procesador"></select>
    </div>
    <div class="form-group">
        <label asp-for="ID_Memoria" class="control-label"></label>
        <select asp-for="ID_Memoria" class ="form-control" asp-items="ViewBag.ID_Memoria"></select>
    </div>
    <div class="form-group">
        <label asp-for="ID_DiscoDuro" class="control-label"></label>
        <select asp-for="ID_DiscoDuro" class ="form-control" asp-items="ViewBag.ID_DiscoDuro"></select>
    </div>
    <div class="form-group">
        <input type="submit" value="Create" class="btn btn-primary" />
    </div>
</form>

错误信息

An unhandled exception occurred while processing the request.
NullReferenceException: Object reference not set to an instance of an object.

Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.GetListItemsWithValueField()

完整调用栈

Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.GetListItemsWithValueField()
Microsoft.AspNetCore.Mvc.Rendering.MultiSelectList.GetEnumerator()
System.Collections.Generic.List<T>..ctor(IEnumerable<T> collection)
System.Linq.Enumerable.ToList<TSource>(IEnumerable<TSource> source)
Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.GenerateGroupsAndOptions(string
optionLabel, IEnumerable selectList,
ICollection currentValues)
Microsoft.AspNetCore.Mvc.ViewFeatures.DefaultHtmlGenerator.GenerateSelect(ViewContext
viewContext, ModelExplorer modelExplorer, string optionLabel, string
expression, IEnumerable selectList,
ICollection currentValues, bool allowMultiple, object
htmlAttributes)
Microsoft.AspNetCore.Mvc.TagHelpers.SelectTagHelper.Process(TagHelperContext
context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.TagHelpers.TagHelper.ProcessAsync(TagHelperContext
context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.RunAsync(TagHelperExecutionContext
executionContext)
AspNetCoreGeneratedDocument.Views_Activos_Create.b__19_0()
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.GetChildContentAsync(bool
useCachedResult, HtmlEncoder encoder)
Microsoft.AspNetCore.Mvc.TagHelpers.RenderAtEndOfFormTagHelper.ProcessAsync(TagHelperContext
context, TagHelperOutput output)
Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner.g__Awaited|0_0(Task
task, TagHelperExecutionContext executionContext, int i, int count)
AspNetCoreGeneratedDocument.Views_Activos_Create.ExecuteAsync()
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage
page, ViewContext context)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage
page, ViewContext context, bool invokeViewStarts)
Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext context)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext
viewContext, string contentType, Nullable statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext
viewContext, string contentType, Nullable statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ActionContext
actionContext, IView view, ViewDataDictionary viewData,
ITempDataDictionary tempData, string contentType, Nullable
statusCode)
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewResultExecutor.ExecuteAsync(ActionContext
context, ViewResult result)
Microsoft.AspNetCore.Mvc.ViewResult.ExecuteResultAsync(ActionContext
context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|22_0(ResourceInvoker
invoker, IActionResult result)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|30_0<TFilter,
TFilterAsync>(ResourceInvoker invoker, Task lastTask, State next,
Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed
context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext<TFilter,
TFilterAsync>(ref State next, ref Scope scope, ref object state, ref
bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|25_0(ResourceInvoker
invoker, Task lastTask, State next, Scope scope, object state, bool
isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed
context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker
invoker)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker
invoker)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext
context)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext
context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext
context)

解决方案

异常根源在MultiSelectList.GetListItemsWithValueField(),说明生成下拉选项时存在空引用,按以下步骤排查修复:

  1. 统一SelectList的Display字段
    对比GET和POST方法的SelectList创建逻辑:

    • GET方法中用"Marca"作为下拉选项的显示字段
    • POST方法中却将DiscoDuro、Memoria、Procesador的显示字段改成了"Modelo"
      如果这些实体类中没有Modelo属性,或者该属性值为null,就会触发空引用异常。
      修复:将POST方法中的显示字段统一改为"Marca",或确认实体类中Modelo属性存在且有值:
    ViewData["ID_DiscoDuro"] = new SelectList(_context.DiscoDuro, "id", "Marca", activo.ID_DiscoDuro);
    ViewData["ID_Memoria"] = new SelectList(_context.Memoria, "id", "Marca", activo.ID_Memoria);
    ViewData["ID_Procesador"] = new SelectList(_context.Procesador, "id", "Marca", activo.ID_Procesador);
    
  2. 确保关联表数据源不为空
    如果_context.DiscoDuro等查询返回null或空集合,创建SelectList时会引发异常。添加空值判断:

    ViewData["ID_DiscoDuro"] = _context.DiscoDuro?.Any() == true
        ? new SelectList(_context.DiscoDuro, "id", "Marca", activo.ID_DiscoDuro)
        : new SelectList(Enumerable.Empty<DiscoDuro>(), "id", "Marca");
    
  3. 优化下拉列表的空选项处理
    在View的下拉列表中添加默认空选项,避免用户未选择时提交null的潜在问题:

    <select asp-for="ID_Usuario" class="form-control" asp-items="ViewBag.ID_Usuario">
        <option value="">-- 请选择用户 --</option>
    </select>
    

内容的提问来源于stack exchange,提问作者yzkael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 03:24:56