一个或多个实体的验证失败。有关详细信息,请参阅 'EntityValidationErrors' 属性。 ASP.NETMVC

Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. ASP.NET MVC

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

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

有两部分我用 // strange 注释对其进行了注释,这意味着我不知道是哪里发生了错误或类似的错误。

感谢阅读我的问题。

这是我的 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>
}

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

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

[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; } 但让我们看看。

希望对您有所帮助。

看看你的模型定义

// 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

阅读更多关于数据验证的信息

您应该使用 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
            );
    }

到时候你就会知道哪些记录是异常的。