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

如何在MVC视图表格中避免NullReferenceException并实现数据更新?

MVC+Entity Framework工厂表格显示问题解决方案

问题背景

基于MVC和Entity Framework的Web项目,包含Company和Plant两张表,Plant通过CompanyId外键与Company关联。业务流程为:首页输入公司ID创建公司→跳转至公司页填写名称、地址等信息→跳转至工厂页添加同属该公司的新工厂。首次进入工厂页时无工厂数据,显示表格时触发NullReferenceException,添加else分支显示默认值后问题仍存在,排查发现Model本身为null。需要实现:

  1. 工厂表格正常显示(无数据时展示友好提示)
  2. 提交新工厂后表格自动更新

问题分析

  1. 空引用层级未覆盖:现有代码仅判断Model.Company.Plants是否为null,但未处理Model为null、Model.Company为null的情况,任意一层为空都会触发异常
  2. 表格结构错误:循环渲染工厂数据时用<th>代替<td>,且未用<tr>包裹每行数据,破坏表格布局
  3. 控制器未正确传递模型:首次进入工厂页时,控制器未确保传递有效的ViewModel,导致视图接收的Model为null

修复方案

1. 视图层修复(核心)

逐层判断空值,修正表格结构,确保无数据时展示友好提示:

<table class="table">
    <thead>
        <tr>
            <th style="width:120px;">Plant Number</th>
            <th>Plant Name</th>
            <th>Plant Definition</th>
            <th>Update</th>
            <th>Delete</th>
        </tr>
    </thead>
    <tbody>
        @* 逐层判断空值:先判断Model,再判断Company,最后判断Plants集合 *@
        @if (Model != null && Model.Company != null && Model.Company.Plants != null && Model.Company.Plants.Any())
        {
            foreach (var item in Model.Company.Plants)
            {
                <tr>
                    <td>@item.PlantNo</td>
                    <td>@item.PlantName</td>
                    <td>@item.PlantDefinition</td>
                    <td><a href="#">Update</a></td>
                    <td><a href="#">Delete</a></td>
                </tr>
            }
        }
        else
        {
            @* 无数据时展示单行提示,覆盖所有列 *@
            <tr>
                <td colspan="5" class="text-center">暂无工厂数据,可添加新工厂</td>
            </tr>
        }
    </tbody>
</table>

2. 控制器层修复(确保模型有效)

工厂页的Action需确保传递有效的ViewModel,首次进入时根据公司ID从数据库加载关联数据:

public class PlantController : Controller
{
    private readonly YourDbContext _context;

    public PlantController(YourDbContext context)
    {
        _context = context;
    }

    // 工厂页入口,接收公司ID
    public async Task<IActionResult> Index(int companyId)
    {
        // 加载公司及关联的工厂数据,Include确保EF加载关联集合
        var company = await _context.Companies
            .Include(c => c.Plants)
            .FirstOrDefaultAsync(c => c.Id == companyId);

        if (company == null)
        {
            // 公司不存在时返回404或初始化空模型
            return NotFound("指定公司不存在");
        }

        // 假设ViewModel包含Company属性
        var viewModel = new PlantViewModel
        {
            Company = company,
            CurrentCompanyId = companyId
        };

        return View(viewModel);
    }

    // 提交新工厂的Post方法
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create(Plant plant)
    {
        if (ModelState.IsValid)
        {
            _context.Add(plant);
            await _context.SaveChangesAsync();
            // 保存成功后重定向回工厂列表页,自动刷新数据
            return RedirectToAction(nameof(Index), new { companyId = plant.CompanyId });
        }
        // 验证失败时返回视图,需确保ViewModel有效
        var viewModel = new PlantViewModel
        {
            Company = await _context.Companies.Include(c => c.Plants).FirstOrDefaultAsync(c => c.Id == plant.CompanyId),
            NewPlant = plant
        };
        return View(viewModel);
    }
}

3. 提交后自动更新实现

  • 页面刷新式更新:如上述控制器代码,提交成功后通过RedirectToAction重定向回工厂列表页,重新查询最新数据,表格自动更新
  • 无刷新更新(可选):用AJAX提交表单,成功后动态向表格添加新行:
// 假设表单ID为plantForm
$("#plantForm").submit(function(e) {
    e.preventDefault();
    $.ajax({
        url: $(this).attr("action"),
        method: $(this).attr("method"),
        data: $(this).serialize(),
        success: function(response) {
            // 动态添加新行到表格tbody
            var newRow = `<tr>
                <td>${response.plantNo}</td>
                <td>${response.plantName}</td>
                <td>${response.plantDefinition}</td>
                <td><a href="#">Update</a></td>
                <td><a href="#">Delete</a></td>
            </tr>`;
            $("table tbody").append(newRow);
            // 清空表单
            $("#plantForm")[0].reset();
        }
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:47:21