C# ViewModel 根据关系创建数据库记录时表单验证为空错误

问题描述 投票:0回答:1

尝试了解 ViewModel,但当表单验证失败时,我收到 null 错误。 仅供参考,最初加载视图时不会发生错误。 当表单验证失败时加载视图时,似乎找不到所需的数据。

我还认为我尝试保存数据的方式存在问题,这可能是导致表单验证错误的原因。

ViewModel如下

using NVFlexo.Models;

namespace NVFlexo.ViewModels;

public class ItemAndItemCategoriesViewModel
{
    public Item Item { get; set; }
    public IEnumerable<ItemCategory> ItemCategories { get; set; }
}

在控制器中创建操作 --> 没有错误,并且视图按预期加载所有必需的数据

public IActionResult Create()
    {
        ItemAndItemCategoriesViewModel itemAndItemCategories = new ItemAndItemCategoriesViewModel();
        itemAndItemCategories.ItemCategories = _itemCategoriesService.getAllCategories();
        return View(itemAndItemCategories);
    }

表单中发生错误的create方法

[HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult Create(ItemAndItemCategoriesViewModel viewModel)
    {
        if (ModelState.IsValid)
        {
            ItemCategory cat = _itemCategoriesService.getById(viewModel.Item.ItemCategory.Id);
            
            Item newItem = new Item();
            newItem.ItemCode = viewModel.Item.ItemCode;
            newItem.ItemDescription = viewModel.Item.ItemDescription;
            newItem.Cost = viewModel.Item.Cost;
            newItem.SalePrice = viewModel.Item.SalePrice;
            newItem.Density = viewModel.Item.Density;
            newItem.Micrones = viewModel.Item.Micrones;
            newItem.ItemCategory = cat;
            _db.Items.Add(newItem);
            _db.SaveChanges();
            TempData["success"] = "Item Created Successfully";
            return RedirectToAction("Index");
        }
        ItemAndItemCategoriesViewModel itemAndItemCategories = new ItemAndItemCategoriesViewModel();
        itemAndItemCategories.ItemCategories = _itemCategoriesService.getAllCategories();
        return View(viewModel);
    }

可能出现问题的视图

@using NVFlexo.ViewModels;

@model ItemAndItemCategoriesViewModel;

@{
    ViewBag.Title = "Create New Item";
    Layout = "_Layout";
}

<form method="post">
    <div class="border p-3 mt-4">
        <div class="row pb-2">
            <h2 class="text-primary">Create Item</h2>
            <hr/>
        </div>
        <div asp-validation-summary="All" class="text-danger"></div>
        <div class="mb-3">
            <label asp-for="Item.ItemCode"></label>
            <input asp-for="Item.ItemCode" class="form-control" />
            <span asp-validation-for="Item.ItemCode" class="text-danger"></span>
        </div>
        <div class="mb-3">
            <label asp-for="Item.ItemDescription"></label>
            <input asp-for="Item.ItemDescription" class="form-control" />
            <span asp-validation-for="Item.ItemDescription" class="text-danger"></span>
        </div>
        <div class="mb-3">
            <label asp-for="Item.Cost"></label>
            <input asp-for="Item.Cost" class="form-control" type="number"/>
            <span asp-validation-for="Item.Cost" class="text-danger"></span>
        </div>
        <div class="mb-3">
            <label asp-for="Item.SalePrice"></label>
            <input asp-for="Item.SalePrice" class="form-control" type="number"/>
            <span asp-validation-for="Item.SalePrice" class="text-danger"></span>
        </div>
        <div class="mb-3">
            <label asp-for="Item.Density"></label>
            <input asp-for="Item.Density" class="form-control" type="number"/>
            <span asp-validation-for="Item.Density" class="text-danger"></span>
        </div>
        <div class="mb-3">
            <label asp-for="Item.Micrones"></label>
            <input asp-for="Item.Micrones" class="form-control" type="number"/>
            <span asp-validation-for="Item.Micrones" class="text-danger"></span>
        </div>
        <div class="mb-3">
            <label asp-for="Item.ItemCategory"></label>
            <select class="form-control" asp-for="Item.ItemCategory">
                @foreach (var category in Model.ItemCategories)
                {
                    <option value="@category.Id">@category.CategoryName</option>
                }
            </select>
            <span asp-validation-for="Item.ItemCategory" class="text-danger"></span>
        </div>
        <button type="submit" class="btn btn-primary" style="width: 150px">Create Item</button>
        <a asp-controller="Item" asp-action="Index" class="btn btn-secondary" style="width: 150px;">Back to List</a>
    </div>
</form>

@section Scripts
{
    @{
        <partial name="_ValidationScriptsPartial"/>
    }
}

我得到的错误

NullReferenceException:未将对象引用设置为实例的实例 目的。 AspNetCoreGenerateDocument.Views_Item_Create.b__25_41() 在 Create.cshtml,第 50 行

第 50 行出现错误:

@foreach (var category in Model.ItemCategories)

堆栈跟踪前几行

AspNetCoreGenerateDocument.Views_Item_Create.b__25_41() 在Create.cshtml中 + @foreach(Model.ItemCategories 中的 var 类别) Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext.SetOutputContentAsync() AspNetCoreGenerateDocument.Views_Item_Create.b__25_0() 在Create.cshtml中 +

商品型号

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;

namespace NVFlexo.Models;

[Index(nameof(ItemCode), IsUnique = true)]
public class Item
{
    [Key]
    public int Id { get; set; }
    public string ItemCode { get; set; }
    public string ItemDescription { get; set; }
    public double Cost { get; set; }
    public double SalePrice { get; set; }
    public double Micrones { get; set; }
    public double Density { get; set; }
    
    public DateTime CreatedAt { get; set; } = DateTime.Now;
    [DisplayName("Item Category")]
    public ItemCategory ItemCategory { get; set; }
}

感谢对此的帮助。可能我搞砸了我的模型或 ViewModel

c# asp.net-mvc mvvm viewmodel
1个回答
0
投票

你试过这个吗?

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create(ItemAndItemCategoriesViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        ItemCategory cat = _itemCategoriesService.getById(viewModel.Item.ItemCategory.Id);

        Item newItem = new Item();
        newItem.ItemCode = viewModel.Item.ItemCode;
        newItem.ItemDescription = viewModel.Item.ItemDescription;
        newItem.Cost = viewModel.Item.Cost;
        newItem.SalePrice = viewModel.Item.SalePrice;
        newItem.Density = viewModel.Item.Density;
        newItem.Micrones = viewModel.Item.Micrones;
        newItem.ItemCategory = cat;
        _db.Items.Add(newItem);
        _db.SaveChanges();
        TempData["success"] = "Item Created Successfully";
        return RedirectToAction("Index");
    }
    viewModel.ItemCategories = _itemCategoriesService.getAllCategories();
    return View(viewModel);
}
© www.soinside.com 2019 - 2024. All rights reserved.