【问题标题】:ASP.NET Core MVC modifying entity causes NullReferenceExceptionASP.NET Core MVC 修改实体导致 NullReferenceException
【发布时间】:2021-09-20 09:44:37
【问题描述】:

我面临一个问题,你们中的大多数人(包括我)都会通过在表单中​​放置隐藏输入来立即解决,但这次我几乎尝试了所有方法。我想通过添加 SolarPanelType 实体来修改 InputForm 实体。由于其他选项的负载,我使用嵌入的视图模型,如您所见

public class InputFormViewModel
    {
        public InputForm InputForm { get; set; }
        public IEnumerable<TetoTipus> TetoTipusEnumerable { get; set; }
        public IEnumerable<TetoFedes> TetoFedesEnumerable { get; set; }
        public IEnumerable<TetoDoles> TetoDolesEnumerable { get; set; }
        public IEnumerable<NapelemElhelyezes> NapelemElhelyezesEnumerable { get; set; }
        public IEnumerable<NapelemTipus> NapelemTipusEnumerable { get; set; }
    }
public class ModifyInputFormViewModel
    {
        public InputFormViewModel InputFormViewModel;
        public SelectList SolarPanelTypesList { get; set; }
    }

然后我像这样在我的控制器中初始化它们

public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }
            ModifyInputFormViewModel modifyInputFormViewModel = new()
            {
                InputFormViewModel = new InputFormViewModel
                {
                    InputForm = await _inputFormService.FindInputFormAsync(id),
                    TetoTipusEnumerable = await _inputFormService.GetTetoTipusokAsync(),
                    TetoFedesEnumerable = await _inputFormService.GetTetoFedesekAsync(),
                    TetoDolesEnumerable = await _inputFormService.GetTetoDolesekAsync(),
                    NapelemElhelyezesEnumerable = await _inputFormService.GetNapelemElhelyezesekAsync(),
                    NapelemTipusEnumerable = await _inputFormService.GetNapelemTipusokAsync()
                },
                SolarPanelTypesList = new SelectList(await _solarPanelTypeService.GetSolarPanelTypesAsync(), "ID", "DisplayString")
            };
            if (modifyInputFormViewModel.InputFormViewModel.InputForm == null)
            {
                return NotFound();
            }
            return View(modifyInputFormViewModel);
        }

还有POST方法

[HttpPost, ValidateAntiForgeryToken, Authorize]
        public async Task<IActionResult> Edit(int id, ModifyInputFormViewModel modifyInputFormViewModel)
        {
            if (id != modifyInputFormViewModel.InputFormViewModel.InputForm.ID)
            {
                return NotFound();
            }
            if (ModelState.IsValid)
            {
                await _inputFormService.ModifyInputFormAsync(modifyInputFormViewModel.InputFormViewModel.InputForm);
                return RedirectToAction(nameof(Index));
            }
            return View(modifyInputFormViewModel);
        }

最后,这是编辑视图的关键部分

<form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <input type="hidden" asp-for="InputFormViewModel.InputForm.ID" />
            <div class="form-group">
                <label asp-for="InputFormViewModel.InputForm.SolarPanelType" class="control-label"></label>
                <select asp-for="InputFormViewModel.InputForm.SolarPanelTypeID" asp-items="@Model.SolarPanelTypesList" class="form-control"></select>
            </div>
            <div class="form-group">
                <label asp-for="InputFormViewModel.InputForm.MonthlyElectricityBill" class="control-label"></label>
                <input asp-for="InputFormViewModel.InputForm.MonthlyElectricityBill" class="form-control" />
                <span asp-validation-for="InputFormViewModel.InputForm.MonthlyElectricityBill" class="text-danger"></span>
            </div>

            <section id="TetoTipusSection">
                <h5>@Html.DisplayNameFor(model => model.InputFormViewModel.InputForm.TetoTipus)</h5>
                <p>
                    @foreach (TetoTipus tetoTipus in Model.InputFormViewModel.TetoTipusEnumerable)
                    {
                        <label>
                            <input type="radio" asp-for="InputFormViewModel.InputForm.TetoTipusID" value="@tetoTipus.ID" /> @tetoTipus.Name
                        </label>
                        <br />
                    }
                </p>
                <hr />
            </section>

            [...]
        </form>

最后一个重要信息是视图完全按照我的意愿呈现,隐藏的输入正确包含 InputForm.ID,但是 post 方法接收到 NULL 值。

【问题讨论】:

  • the view renders EXACTLY what I want, the hidden input contains InputForm.ID correctly, but then the post method receives NULL value你在浏览器f12开发者工具网络标签中查看过实际发布的数据吗?请确保您发布的表单数据的键与您的模型属性匹配。

标签: c# asp.net asp.net-mvc asp.net-core crud


【解决方案1】:

更新你的代码如下:-

<form asp-action="Edit" method="post" enctype="multipart/form-data">

和你的控制器:-

[HttpPost]
public async Task<IActionResult> Edit(int? ID){...}

希望它能解决您的问题。

【讨论】:

  • 感谢您的努力,但已经添加了 HttpPost,再次出现同样的错误。
  • @MészárosBarnabás 在控制器中使用您的参数ID 而不是id。因为您将 ID 从视图传递到控制器操作。
【解决方案2】:

修复视图,因为您使用 AntiForgeryToken 将其添加到表单

<form asp-action="Edit" method="post">
 @Html.AntiForgeryToken()

和action输入参数要和model一样,去掉id

 public async Task<IActionResult> Edit( ModifyInputFormViewModel modifyInputFormViewModel)
{
 var id= modifyInputFormViewModel.InputFormViewModel.InputForm.ID;
.......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 2018-09-22
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多