我一直在努力完成一个简单的应用程序,我在暑期实习时给予了练习。我几乎没有ASP.NET背景,所以我得到了额外的工作。我试图从c#中的http post函数获取数据库条目,但是当函数运行时会抛出验证错误。我一直试图找出错误的原因,但我似乎无法弄清楚为什么它不起作用。任何帮助表示赞赏。
这是错误:
一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationErrors”属性。 描述:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪,以获取有关错误及其在代码中的起源位置的更多信息。
异常详细信息:System.Data.Entity.Validation.DbEntityValidationException:一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationErrors”属性。
来源错误:
第130行:db.Entry(productNote).State = EntityState.Modified;
第131行:db.SaveChanges();
第132行:返回RedirectToAction(“索引”);
源文件:C:\ Users \ Morph \ Documents \ Visual Studio 2015 \ Projects \ NotesWebApp \ NotesWebApp \ Controllers \ ProductsController.cs Line:131
这是我的Controller中的http post函数:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index([Bind(Include = "ID,ProductID,NoteText,CreateDate,Archived")] ProductNote productNote)
{
Response.Write("<script type=\"text/javascript\">alert('Works');</script>");
if (ModelState.IsValid)
{
db.Entry(productNote).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return RedirectToAction("Index");
}
以下是我提交给该职能部门的表格:
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(noteItem => note.ID)
@Html.HiddenFor(noteItem => note.ProductID)
@Html.HiddenFor(noteItem => note.NoteText)
@Html.HiddenFor(noteItem => note.CreateDate)
<div class="checkbox">
@Html.EditorFor(noteItem => note.Archived)
@Html.ValidationMessageFor(noteItem => note.Archived, "", new { @class = "text-danger" })
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
}
答案 0 :(得分:1)
错误的原因是您在foreach
循环中生成表单,因此控件具有与您的模型无关的name
属性(请参阅HTML Table to ADO.NET DataTable了解更多信息信息)。因此,您的POST方法只会使用默认属性初始化新的ProductNote
(大概ID
为int
,因此其值为0
。)
即使您确实生成了正确的视图,您也会通过生成大量不必要的HTML并将其发回来降级您的应用,但更重要的是,恶意用户可以轻松更改ProductNote
中的所有数据你不知道的桌子。
根据您的评论,您只想提交一个表单,将单个ProductNote
标记为已存档。首先创建一个表示您想要做的事情的方法
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Archive (int ID)
{
// Get the original
ProductNote model = db.ProductNote.FirstOrDefault(x => x.ID == ID);
// If the user has the permission to archive and the model is not null
model.Archived = true;
db.SaveChanges();
return RedirectToAction("Index");
}
将视图更改为
@foreach(var note in Model.ProductNotes)
{
@Html.DisplayFor(m => note.NoteText)
....
@using (Html.BeginForm("Archive", "Products", new { id = note.ID }))
{
@Html.AntiForgeryToken()
<input type="submit" value="Archive" />
}
}
您还需要考虑处理表单.submit()
事件以显示确认消息(或者只是使用指向显示确认页面的GET方法的链接并从那里进行POST)。此外,您应该考虑使用ajax发布ID
值,以便您可以停留在同一页面上并继续存档ProductNote
个项目。
答案 1 :(得分:1)
更新实体数据模型将起作用
答案 2 :(得分:0)
尝试使用
db.Entry(productNote).State = EntityState.Modified;
不
$(document)
.on('click.bs.dropdown.data-api', clearMenus)
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
.on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
.on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
.on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
}(jQuery);