【问题标题】:Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. ASP.NET MVC一个或多个实体的验证失败。有关更多详细信息,请参阅“EntityValidationErrors”属性。 ASP.NET MVC
【发布时间】:2026-01-05 03:40:01
【问题描述】:

我遇到了标题所示的错误。我试图寻找解决方案,但我得到的只是关于使用try catch 代码块的解决方案。

我一直在使用我制作的课程文档来指导我做这个项目,但是我这次遇到的错误,我不知道哪个部分出了问题以及如何检查错误的部分。

我用// strange cmets 评论了两部分,这意味着我不知道错误发生在哪里或类似的地方。

感谢您阅读我的问题。

这是我的 PetRescued 模型

public class PetRescued
{
    public int Id { get; set; }

    [Required]
    [StringLength(255)]
    public string PetName { get; set; }

    public int PetAge { get; set; }

    [Required]
    [StringLength(6)]
    public string PetGender { get; set; }

    public short PetWeightInKg { get; set; }

    public DateTime DateWhenRescued { get; set; }

    public PetSpecies PetSpecies { get; set; }

    public byte PetSpeciesId { get; set; }

}

这是我的 PetRescued 控制器

 public ActionResult New() //populate form
    {
        var petspecies = _context.PetSpecieses.ToList();

        var viewModel = new PetRescuedViewModel
        {
            PetSpecies = petspecies
        };

        return View("PetRescued", viewModel);
    }

[HttpPost]
public ActionResult Save(PetRescued petRescued)
{
    if (petRescued.Id == 0)
        _context.PetRescueds.Add(petRescued);
    else
    {
        var petRescuedInDb = _context.PetRescueds.Single(c => c.Id == petRescued.Id);
        petRescuedInDb.PetName = petRescued.PetName;
        petRescuedInDb.PetAge = petRescued.PetAge;
        petRescuedInDb.PetGender = petRescued.PetGender;
        petRescuedInDb.PetWeightInKg = petRescued.PetWeightInKg;
        petRescuedInDb.PetSpeciesId = petRescued.PetSpeciesId; //strange
        petRescuedInDb.DateWhenRescued = petRescued.DateWhenRescued;
     }

    _context.SaveChanges();
    return RedirectToAction("Index", "PetRescued");
}

这是我的 PetRescued ViewModel

public class PetRescuedViewModel
{
    public IEnumerable<PetSpecies> PetSpecies { get; set; }

    public PetRescued PetRescueds { get; set; }


    public PetRescuedViewModel()
    {
        PetRescueds = new PetRescued(); 
    }
}

这是我的 PetRescued 表格

@using (Html.BeginForm("Save", "PetRescued"))
{
<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetName)
    @Html.TextBoxFor(m => m.PetRescueds.PetName, new { @class = "form-control" })
</div>

//strange
<div class="form-group">
    @Html.LabelFor(m => m.PetSpecies)
    @Html.DropDownListFor(m => m.PetRescueds.PetSpeciesId, new SelectList(Model.PetSpecies, "Id", "SpeciesName"), "Select A Species", new {@class = "form-control"})    
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetAge)
    @Html.TextBoxFor(m => m.PetRescueds.PetAge, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetGender)
    @Html.TextBoxFor(m => m.PetRescueds.PetGender, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetWeightInKg)
    @Html.TextBoxFor(m => m.PetRescueds.PetWeightInKg, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.DateWhenRescued)
    @Html.TextBoxFor(m => m.PetRescueds.DateWhenRescued, "{0:d MMM yyyy}", new { @class = "form-control" }) 
</div>

@Html.HiddenFor(m => m.PetRescueds.Id)
<button type="submit" class="btn btn-primary">Save</button>
}

【问题讨论】:

  • 我没有看到你的//strange cmets。
  • 它们在 PetRescued Controller "petRescuedInDb.PetSpeciesId = petRescued.PetSpeciesId" 和 PetRescued Form "DropDownList" 语句中。
  • 对不起。我完全错过了!
  • 有多个问题和答案涵盖了您遇到的错误。你审查过其中任何一个吗?例如,this question 有一些答案可以显示如何查看实际的验证错误,这通常是最有帮助的更改。
  • 您视图中的模型是 PetRescuedViewModel,因此 POST 方法中的参数必须是 PetRescuedViewModel,而不是 PetRescued,正如我在您之前的问题中指出的那样(同样 - 视图模型不包含数据模型!)

标签: asp.net asp.net-mvc asp.net-mvc-4 asp.net-mvc-5


【解决方案1】:

查看您的模型定义

// This means this value is required 
// and should not be greater than 255 characters 
[Required]
[StringLength(255)]
public string PetName { get; set; }

// This means this value is required 
// and should not be greater than 6 characters 
[Required]
[StringLength(6)]
public string PetGender { get; set; }

因此,要么您没有从您的客户端应用发送值,要么它大于您声明的限制。 将您的操作方法更改为此以在后端验证您的模型(您永远不应该信任客户端输入)

[HttpPost]
public ActionResult Save(PetRescued petRescued)
{
    if (ModelState.IsValid) // Check for errors
    {
        if (petRescued.Id == 0)
            _context.PetRescueds.Add(petRescued);
        else
        {
            var petRescuedInDb = _context.PetRescueds.Single(c => c.Id == petRescued.Id);
            petRescuedInDb.PetName = petRescued.PetName;
            petRescuedInDb.PetAge = petRescued.PetAge;
            petRescuedInDb.PetGender = petRescued.PetGender;
            petRescuedInDb.PetWeightInKg = petRescued.PetWeightInKg;
            petRescuedInDb.PetSpeciesId = petRescued.PetSpeciesId; //strange
            petRescuedInDb.DateWhenRescued = petRescued.DateWhenRescued;
         }

        _context.SaveChanges();
        return RedirectToAction("Index", "PetRescued");
    }
    else
        return View(petRescued); // Return the same view with the original data
                                 // or with the correct model of your view, at least
}

更新

更正您的视图模型以反映您的正确数据。这意味着,确保您将正确的模型发送到后端。 ASP.Net MVC 有一个叫做 Model Binding 的东西,它是用于将从客户端接收到的数据转换为 C# 模型的机制。默认情况下,它通过检测从客户端传递的值的名称并找到与模型属性的精确映射来工作。这意味着在您看来,您正在声明这一点

    @Html.TextBoxFor(m => m.PetRescueds.PetName, new { @class = "form-control" })

因此,如果您检查浏览器发送的数据,您会看到表单数据包含类似

PetRescueds.PetAge: whatever_the_client_typed

不会映射到您的模型,因为您的模型没有名为 PetRescueds 的属性和名为 PetName 的子属性,所以您的动作模型直接是 PetRescued 模型。所以要么通过直接指定名称 attr 来改变你的视图,就像这样

    @Html.TextBox("PetName", Model.PetRescueds.PetName, new { @class = "form-control" })

或者更改您的操作模型以反映您的视图模型定义。无论哪种方式,您的视图模型都应该通过您的操作和视图保持一致。否则,尽管您在视图中正确填充了空值,或者无论您在控制器操作上实际创建了什么,您最终都会在您的操作模型中收到空值,或者在视图中显示空值。

所以,基本上,检查您的模型定义。确保您使用正确的模型定义来显示在您的视图中。确保您的视图正确定义为您期望在后端控制器中接收的内容。

然后,更改视图以包含从服务器检索到的验证错误

@using (Html.BeginForm("Save", "PetRescued"))
{
<!-- This will show your errors-->
@Html.ValidationSummary()
<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetName)
    <!-- Or you can show errors for each model property -->
    <!-- like this -->
    @Html.ValidationMessageFor(m => m.PetRescueds.PetName);
    @Html.TextBox("PetName", Model.PetRescueds.PetName, new { @class = "form-control" })
</div>

//strange
<div class="form-group">
    @Html.LabelFor(m => m.PetSpecies)
    @Html.DropDownListFor(m => m.PetRescueds.PetSpeciesId, new SelectList(Model.PetSpecies, "Id", "SpeciesName"), "Select A Species", new {@class = "form-control"})    
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetAge)
    @Html.TextBoxFor(m => m.PetRescueds.PetAge, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetGender)
    @Html.TextBoxFor(m => m.PetRescueds.PetGender, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.PetWeightInKg)
    @Html.TextBoxFor(m => m.PetRescueds.PetWeightInKg, new { @class = "form-control" })
</div>

<div class="form-group">
    @Html.LabelFor(m => m.PetRescueds.DateWhenRescued)
    @Html.TextBoxFor(m => m.PetRescueds.DateWhenRescued, "{0:d MMM yyyy}", new { @class = "form-control" }) 
</div>

@Html.HiddenFor(m => m.PetRescueds.Id)
<button type="submit" class="btn btn-primary">Save</button>
}

您可以在Microsofts's 阅读有关数据验证的更多信息

【讨论】:

  • 我试过你的方法,但是这行代码有问题@Html.DropDownListFor(m =&gt; m.PetRescueds.PetSpeciesId, new SelectList(Model.PetSpecies, "Id", "SpeciesName"), "Select A Species", new {@class = "form-control"})我非常怀疑这是根本原因,但我不知道如何解决这个问题。
  • 我刚刚复制了你的代码。你是如何填充你的模型的?您应该首先验证您的模型创建,然后再将其传递给您的视图。因此,步骤是: - 验证您的模型(确保您将正确的数据从控制器传递到您的视图) - 验证您的视图定义(确保您的 HTML 组件根据您的模型需要正确定义) - 验证您的模型数据验证(确保从客户端返回的数据,例如在客户端填充您的视图后从浏览器接收的数据,根据您的规范是正确的。这是您最初的问题。
  • 您的原始问题有几个问题。您的视图未发送正确的模型(您为视图声明了错误的模型,它与控制器预期的模型不同)。您的控制器未验证从客户端收到的数据。您的视图未显示验证错误。我更新了答案以显示所有这些方面。
  • 感谢您指出问题,我会一一检查问题,但目前我正在努力解决如何在视图中为 DropDownList 编写语句,“??”即使我尝试使用 IEnumerable@Html.DropDownList("Pet Species", ?? , new SelectList (Model.PetSpecieses, "Id", "Name"), "Select Species Type", new { @class = "form-control" }),部分也会不断出错
  • 好的,这是一个不同的问题。我建议您验证所有用户提供的答案。我的意见是您应该将您的问题标记为已解决,因为通过阅读所有答案,您的原始问题的解决方案已被提供,并提出另一个不同的问题,以使该特定线程专注于您的原始问题。
【解决方案2】:

让我们尝试解决这个问题。

首先,让我们更改您的控制器,使其能够处理模型绑定器返回的错误。

[HttpGet]
public ActionResult New() //populate form
{
    var petspecies = _context.PetSpecieses.ToList();

    var viewModel = new PetRescuedViewModel
    {
        PetSpecies = petspecies
    };

    return View("PetRescued", viewModel);
}

[HttpPost]
public ActionResult Save(PetRescuedViewModel viewModel)
{
    if (ModelState.IsValid) // Check for errors
    {
        if (petRescued.Id == 0)
            _context.PetRescueds.Add(petRescued);
        else
        {
            var petRescuedInDb = _context.PetRescueds.Single(c => c.Id == petRescued.Id);
            petRescuedInDb.PetName = viewModel.PetRescued.PetName;
            petRescuedInDb.PetAge = viewModel.PetRescued.PetAge;
            petRescuedInDb.PetGender = viewModel.PetRescued.PetGender;
            petRescuedInDb.PetWeightInKg = viewModel.PetRescued.PetWeightInKg;
            petRescuedInDb.PetSpeciesId = viewModel.PetRescued.PetSpeciesId; //strange
            petRescuedInDb.DateWhenRescued = viewModel.PetRescued.DateWhenRescued;
        }

        _context.SaveChanges();
        return RedirectToAction("Index", "PetRescued");
    }

    viewModel.PetSpecies = _context.PetSpecieses.ToList();  // populate the list again as the contents are lost when the form is submitted.

    return View("PetRescued", viewModel); // validation errors found, so redisplay the same view
}

然后,更改视图以显示错误。我们基本上是在做this 回答建议的事情。

@using (Html.BeginForm("Save", "PetRescued"))
{
    // Displays a summary of all the errors.
    @Html.ValidationSummary() 

    <div class="form-group">
        @Html.LabelFor(m => m.PetRescueds.PetName)
        @Html.TextBoxFor(m => m.PetRescueds.PetName, new { @class = "form-control" })
        // Or you can add this to each property            
        @Html.ValidationMessageFor(m => m.PetRescueds.PetName) 
    </div>

    //strange
    <div class="form-group">
        @Html.LabelFor(m => m.PetSpecies)
        @Html.DropDownListFor(m => m.PetRescueds.PetSpeciesId, new SelectList(Model.PetSpecies, "Id", "SpeciesName"), "Select A Species", new {@class = "form-control"})    
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.PetRescueds.PetAge)
        @Html.TextBoxFor(m => m.PetRescueds.PetAge, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.PetRescueds.PetGender)
        @Html.TextBoxFor(m => m.PetRescueds.PetGender, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.PetRescueds.PetWeightInKg)
        @Html.TextBoxFor(m => m.PetRescueds.PetWeightInKg, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.PetRescueds.DateWhenRescued)
        @Html.TextBoxFor(m => m.PetRescueds.DateWhenRescued, "{0:d MMM yyyy}", new { @class = "form-control" }) 
    </div>

    @Html.HiddenFor(m => m.PetRescueds.Id)
    <button type="submit" class="btn btn-primary">Save</button>
}

以上更改至少会告诉您哪些属性存在问题。

下一步是解决实际问题。如果您执行上述操作并且无法进一步弄清楚,请告诉我它是哪些属性,我会看看。

我猜是public byte PetSpeciesId { get; set; },但让我们看看。

希望这会有所帮助。

【讨论】:

  • 我尝试了你的方法,但我收到此错误“值不能为空。参数名称:项目”,错误显示第 25 行是第 25 行的原因:@Html.DropDownListFor(m => m.PetRescueds.PetSpeciesId, new SelectList(Model.PetSpecies, "Id", "SpeciesName"), "Select A Species", new { @class= "form-control" })。您解决方案的第一步是“return View(viewModel);”告诉我我没有 viewModel 所以我自己创建了一个 var viewModel = new PetRescuedViewModel { PetRescueds = petRescued };
  • 我已更改 public int PetSpeciesId { get;放; } 转换为字节数据类型,但仍然发生错误
  • 你好。我已经更新了我的答案以包含视图模型。您必须具有生成表单的控制器操作。你如何填充public IEnumerable&lt;PetSpecies&gt; PetSpecies { get; set; }
  • 我确实有一个控制器来生成表单,我已经在我的问题中更新了它。我使用“添加迁移”来填充 PetSpecies。 1 个问题先生,我不明白你对这条线的意思是什么 viewModel.PetSpecies = _someMethod.ToPopulate(); // populate the list 填充什么列表?
  • 在您添加 get 方法后,我已经更新了我的答案。重新显示表单时基本上需要重新填充viewModel.PetSpecies列表(它是IEnumerable&lt;PetSpecies&gt;),因为发布表单时内容会丢失。
【解决方案3】:

您应该使用trycatch 方法来查看哪些字段会导致“EntityValidationErrors”:

ActionResult 保存 =>

    try
    {
        _context.SaveChanges();;
    }
    catch (DbEntityValidationException ex)
    {
        var sb = new StringBuilder();

        foreach (var failure in ex.EntityValidationErrors)
        {
            sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType());
            foreach (var error in failure.ValidationErrors)
            {
                sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage);
                sb.AppendLine();
            }
        }

        throw new DbEntityValidationException(
            "Entity Validation Failed - errors follow:\n" +
            sb.ToString(), ex
            );
    }

你会知道哪些记录发生了异常。

【讨论】:

  • 我删除了 Save() 中的所有内容并尝试使用 Try&Catch,我得到的错误是 Object reference not set to an instance of an object. 和这一行Line 25: @Html.DropDownListFor(m =&gt; m.PetRescueds.PetSpeciesId, new SelectList(Model.PetSpecies, "Id", "SpeciesName"), "Select A Species", new { @class = "form-control" }) 是红色的,所以我猜这有问题,但我不知道在哪里......
  • 我再次尝试使用我的代码和您的 try&catch,我发现有一个错误 [DbEntityValidationException: Entity Validation Failed - 错误如下:FWPaws6.Models.PetRescued 验证失败 - PetName:PetName 字段是必需的。 - PetGender : PetGender 字段是必需的。 ] 但我在提交表单之前确实输入了姓名和性别..
  • 您是否在视图顶部声明了模型 => @model mynamespace.Models.RegisterViewModel ?如果不是,也许您可​​以尝试设置您的输入 m.PetRescueds.PetNamem.PetName 等...看起来您的表单没有传输好的模型。
  • 是的,我确实声明了
最近更新 更多