我遇到了这个问题:我无法在控制器中创建一个双“Edit”ActionResult,我的目标是允许匿名用户通过一个只返回输出中一条记录的过滤器来更改多个字段...系统返回此错误,我知道,不知何故,问题与主键有关。
CONTROLLER
// GET:
[Authorize]
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
MyTable mytable = await db.MyTable.FindAsync(id);
if (mytable == null)
{
return HttpNotFound();
}
return View(mytable);
}
[AllowAnonymous]
[HttpGet]
public async Task<ActionResult> EditAnonymus(int? fk_field1, string guid)
{
if (fk_field1 == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var query = (from i in db.MyTable
where i.Guid == guid && i.Fk_Field1==fk_Field1
select new { i.Id }).SingleOrDefault();
MyTable mytable = await db.MyTable.FindAsync(query.Id);
if (mytable == null)
{
return HttpNotFound();
}
return View(mytable);
}
// POST:
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Id,Fk_table1,......")] MyTable mytable)
{
if (ModelState.IsValid)
{
try
{
db.Entry(mytable).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
catch (DbUpdateConcurrencyException ex)
{
Trace.Write(ex.Message);
}
}
return View(mytable);
}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> EditAnonymus([Bind(Include = "Id,........")] MyTable mytable)
{
if (ModelState.IsValid)
{
try
{
db.Entry(mytable).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
catch (DbUpdateConcurrencyException ex)
{
Trace.Write(ex.Message);
}
}
return View(mytable);
}
VIEW(从另一个视图输入的命令)
@Html.ActionLink("Modify Anonymus",
"EditAnonumus", controllerName: "NameController",
routeValues: new
{ fk_table1 = Model.Id, guid = Request.QueryString["guid"] },
htmlAttributes: null)
查看(编辑)
@model ManagingEvent.Models.MyTable
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Anonymus Edit</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
//omiss
<div class="form-group">
@Html.LabelFor(model => model.Cognome, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Field, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Field, "", new { @class = "text-danger" })
</div>
</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>
</div>
}
错误输出(保存后)
存储更新,插入或删除语句会影响意外的行数(0)。自那以后,实体可能已被修改或删除 实体已加载。看到 http://go.microsoft.com/fwlink/?LinkId=472540了解有关的信息 理解和处理乐观并发异常 线程0x518已退出,代码为0(0x0)。
答案 0 :(得分:1)
我认为您的问题与主键无关,但可以是EditAnonymus
方法中的这行代码:
db.Entry(mytable).State = EntityState.Modified;
您正在做的是将实体明确标记为已修改,EF将在您调用SaveChangesAsync()
时尝试更新它,并且期望获取更新的行数(1),但是如果没有更改属性它将获得0(没有更新行),因此它将抛出异常。
我会评论该行并尝试进行简单的fetch-edit-save,看看会发生什么。
答案 1 :(得分:0)
感谢用户449689的指导,我在互联网上搜索,我发现这种方法有效:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> EditAnonymus (int? Id)
{
if (Id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var TableToUpdate = await db.myTable.FindAsync(Id);
if (TryUpdateModel(TableToUpdate, "",
new string[] { "Field1","Field2","....","....","Field x" }))
{
try
{
db.SaveChanges();
return RedirectToAction("Index");
}
catch (DataException /* dex */)
{
//Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}