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



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

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

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

感谢您阅读我的问题。

这是我的宠物救援模型

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; }
}

这是我的宠物救援控制器

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");
}

这是我的宠物获救视图模型

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

public PetRescuedViewModel()
{
PetRescueds = new 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>
}

查看模型定义

// 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 具有称为模型绑定的机制,它是用于将从客户端接收的数据转换为 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" })

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

因此,基本上,请检查模型定义。确保使用正确的模型定义显示在视图中。确保正确定义视图,说明您希望在后端控制器中接收的内容。

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

@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>
}

您可以在Microsoft的

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

首先,让我们更改控制器,以便能够对模型绑定器返回的错误执行某些操作。

[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
}

然后,更改视图以显示错误。 我们基本上是在做这个答案所暗示的。

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

希望这有帮助。

您应该使用trycatch方法来查看哪些字段导致">实体验证错误":

操作结果保存 =>

try
{
_context.SaveChanges();;
}
catch (DbEntityValidationException ex)
{
var sb = new StringBuilder();
foreach (var failure in ex.EntityValidationErrors)
{
sb.AppendFormat("{0} failed validationn", 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
);
}

然后,您将知道哪些记录例外。

相关内容

最新更新