我在MVC中遇到了一个奇怪的问题,该应用程序可以正常运行,然后随着带有发布请求的几个视图的运行,数据库不会更新。我没有收到任何错误;该应用程序的行为几乎像往常一样 ,只是没有实际更新与该特定项目关联的表的行。
我发现,如果我停止Visual Studio运行/调试此应用程序,然后再次运行它,则可以再次成功更新表。是什么导致此问题?我可以通过以下设置重现此问题。
模型
Accounts.cs
public partial class Accounts
{
public int ID { get; set; }
public string AccountName { get; set; }
public string Validated { get; set; }
public string ReValidated { get; set; }
public virtual Accounts_AE Accounts_AE { get; set; }
}
Accounts_AE.cs
public partial class Accounts_AE
{
public int ID { get; set; }
public string DateNoted { get; set; }
public string ActionTaken { get; set; }
public virtual Accounts Accounts { get; set; }
}
查看模型
DatabaseViewModel.cs
namespace AccountManagement.ViewModel
{
public class DatabaseViewModel
{
public IEnumerable<Accounts> DBAccounts { get; set; }
public IEnumerable<Accounts_AE> DBAccountsAE { get; set; }
}
}
查看
Index.cshtml
@model AccountManagement.ViewModel.DatabaseViewModel
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<table class="table">
<tr>
<th>
AccountName
</th>
<th>
Action
</th>
</tr>
@foreach (var item in Model.DBAccounts)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.AccountName)
</td>
<td>
<button class="btn btn-primary" onclick="ActionAway(@item.ID)">Perform Check</button>
</td>
</tr>
}
</table>
<div class="modal fade" id="myModal1">
<div class="modal-dialog modal-lg">
<div class="modal-content" id="mymodalContent" style="padding:15px">
</div>
</div>
</div>
<div class="modal fade" id="myModal2">
<div class="modal-dialog modal-lg">
<div class="modal-content" id="mymodalContent2" style="padding:15px">
</div>
</div>
</div>
<script>
var ActionAway = function (theid) {
var url = "/DB/Validate?id=" + theid;
$('#mymodalContent').load(url, function () {
$('#myModal1').modal("show");
})
}
</script>
<script>
var ActionAway2 = function (theid) {
var url = "/DB/Change?id=" + theid;
$('#mymodalContent2').load(url, function () {
$('#myModal2').modal("show");
})
}
</script>
ConfirmF.cshtml
@model AccountManagement.Models.Accounts_AE
@{
ViewBag.Title = "View";
Layout = null;
}
<div class="modal-header">
<a href="#" class="close">×</a>
<h3 class="modal-title">Confirm Action</h3>
</div>
<div class="modal-body" id="myModalBodyDiv1">
<table>
<tr>
<td width="50%">
<table class="table">
<tr>
<th>Date Flagged</th>
<td>@Html.DisplayFor(model => model.DateNoted)
</tr>
<tr>
<td><button type="button" class="btn btn-primary" id="btnSave">Confirm</button></td>
</tr>
</table>
</td>
<td width="50%">
<table class="table">
<tr>
<th>Account Name</th>
<td>@Html.DisplayFor(x => x.DB_Accounts.AccountName)</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
<script>
$(document).ready(function () {
$("#btnSave").click(function () {
$.ajax({
success: function () {
$("#myModal").modal("hide");
location.reload();
}
})
})
})
</script>
Flagged.cshtml
@model AccountManagement.ViewModel.DatabaseViewModel
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<table class="table table-striped table-bordered">
<tr>
<th>
AccountName
</th>
<th>
Action Account
</th>
</tr>
@foreach (var item in Model.DBAccounts)
{
<tr id="row_@item.ID">
<td>
@Html.DisplayFor(modelItem => item.AccountName)
</td>
<td>
Action Account
</td>
</tr>
<tr>
<th>
Date Flagged:
</th>
<td>
@Html.DisplayFor(x => x.DBAccountsAE.Where(m => m.ID == item.ID).First().DateNoted)
</td>
</tr>
<tr>
<th>
Action Taken
</th>
</tr>
}
</table>
<div class="modal fade" id="myModal1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<a href="#" class="close" data-dismiss="modal">×</a>
<h3 class="modal-title">Action This Account</h3>
</div>
<div class="modal-body" id="myModalBodyDiv1">
</div>
</div>
</div>
</div>
@section Scripts{
<script>
var ActionAway = function (theid) {
var url = "/DB/Edit?id=" + theid;
$('#myModalBodyDiv1').load(url, function () {
$('#myModal1').modal("show");
})
}
</script>
}
Edit.cshtml
@model AccountManagement.Models.Accounts_AE
@{
ViewBag.Title = "View";
Layout = null;
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.ID)
@Html.HiddenFor(model => model.DateNoted)
<table>
<tr>
<td width="50%">
<table class="table">
<tr>
<th>Date Flagged</th>
<td>@Html.DisplayFor(model => model.DateNoted)
</tr>
<tr>
<th>Action Taken</th>
<td>@Html.TextAreaFor(model => model.ActionTaken, new { @class = "form-control", rows = "5" })</td>
</tr>
</table>
</td>
<td width="50%">
<table class="table">
<tr>
<th>Account Name</th>
<td>@Html.DisplayFor(x => x.Accounts.AccountName)</td>
</tr>
</table>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save" class="btn btn-primary" id="btnSave"/>
<button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button>
</td>
</tr>
</table>
</div>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
<script>
$(document).ready(function () {
$("#btnSave").click(function () {
$.ajax({
success: function () {
$("#myModal").modal("hide");
}
})
})
})
</script>
控制器
DBController.cs
namespace AccountManagement.Controllers
{
public class DBController : Controller
{
private AccountEntities db = new AccountEntities();
public ActionResult Index()
{
DatabaseViewModel DBVM = new DatabaseViewModel();
DBVM.DBAccounts = db.Accounts.Where(x => x.Validated == null).ToList();
return View("Index", DBVM);
}
public ActionResult Flagged()
{
DatabaseViewModel DBVM = new DatabaseViewModel();
DBVM.DBAccounts = db.Accounts.Where(x => x.Validated == "F" || (x.ReValidated == "R" && x.Validated == null)).ToList();
DBVM.DBAccountsAE = db.Accounts_AE.ToList();
return View("Flagged", DBVM);
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Accounts_AE actionableEvents = db.Accounts_AE.Find(id);
if (actionableEvents == null)
{
return HttpNotFound();
}
return View(actionableEvents);
}
//Edit Save
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Accounts_AE actionableEvents)
{
if (ModelState.IsValid)
{
DB_Accounts dB_Accounts = db.DB_Accounts.Where(x => x.ID == actionableEvents.ID).First();
dB_Accounts.Validated = null;
dB_Accounts.ReValidated = "R";
db.Entry(dB_Accounts).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Flagged");
}
return View(actionableEvents);
}
public ActionResult Validate(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
DB_Accounts dB_Accounts = db.DB_Accounts.Find(id);
DB_Accounts_AE dB_Accounts_AE = db.DB_Accounts_AE.Find(id);
dB_Accounts_AE.ReviewedBy = User.Identity.Name.ToString();
dB_Accounts_AE.DateNoted = DateTime.Now.ToString("dd MMM yyyy");
dB_Accounts.Validated = "F";
if (ModelState.IsValid)
{
db.Entry(dB_Accounts_AE).State = EntityState.Modified;
db.Entry(dB_Accounts).State = EntityState.Modified;
db.SaveChanges();
}
return View("ConfirmF", dB_Accounts_AE);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
为重现该问题,我从“索引”页面开始。我单击“执行检查”按钮,这会弹出一个模式弹出窗口(ConfirmF)。我单击弹出窗口上的“确认”按钮,然后有问题的项目从页面中消失。然后,我转到“标记”页面。在这里,我单击“操作”按钮,将其保存,然后返回到“索引”页面。该项目现在已重新出现在页面上。
此时应该发生的事情是当我单击“ Perform Check”时,该项目应该像以前一样消失了。但是,实际上没有任何反应。当我调试程序时,我发现它甚至没有击中控制器!这是怎么回事?
简而言之,为了解释我的程序,“索引”页面上的项目是从表中筛选出来的。单击“执行检查”按钮后,它将在该行的表中更改一个值(从NULL),以便该项目不再包含在过滤器中。在“标记”视图中对其进行操作时,它将值更改回NULL,以便再次在“索引”视图中显示。不幸的是,由于“性能检查”按钮将不再可用于更新表(或点击控制器),因此您现在无法重复这些步骤。
如果我停止调试程序,然后重新启动它,则可以成功使用“执行检查”按钮。另外,如果我启动程序并转到“标记”页面以执行某项操作,然后返回到“索引”页面,我也可以成功使用“执行检查”按钮。
换句话说,如果执行索引->标记的->索引,则“执行检查”将失败。如果执行标记->索引,它将成功。我到底在这里做错了什么?我将不胜感激!