我正在开发一个ASP.Net MVC应用程序,并且在试图通过部分回发更新数据库中的数据时遇到了一个bizzare问题。在HTTP、AJAX等方面,我仍然是新手,所以我希望这是一个明显的错误。
基本上,当我试图更新将内容区域链接到评估的表时,更新有时起作用,有时不起作用。bizzare的特点是,在我发布后,我直接从MVC应用程序查询数据库,以确保预期的更改实际上已经完成(这就是所有ViewBag.DebugInfo在下面的代码中所做的)。在任何情况下,查询都返回我希望看到的内容。但是,当我通过SSMS查询表时,我发现更改有时只会发生。
我的MVC应用程序对表的直接查询如何显示更新已经完成,而我却清楚地看到它不是通过SSMS完成的?有没有静音回滚什么的?这是令人恼火的,任何帮助都将不胜感激。
几个信息:
这里是我的类,它获取和更新数据:
public class assessmentContent {
public int? assessmentId { get; set; }
public List<short> baseline { get; set; } = new List<short>();
public List<short> comparison { get; set; } = new List<short>();
public assessmentContent() { if (assessmentId != null) refreshTheData(); }
public assessmentContent(int assessmentId) {
this.assessmentId = assessmentId;
refreshTheData();
}
public void saveTheData() {
List<short> upserts = comparison.Except(baseline).ToList();
List<short> deletes = baseline.Except(comparison).ToList();
foreach (var upsert in upserts)
reval.ach.addAssessmentContent(assessmentId, upsert);
foreach (var delete in deletes)
reval.ach.deleteAssessmentContent(assessmentId, delete);
refreshTheData();
}
void refreshTheData() {
baseline = reval.ach.assessmentContent(assessmentId).ToList();
comparison = reval.ach.assessmentContent(assessmentId).ToList();
}
}当我在MVC应用程序之外使用它时,逻辑工作得很好。因此,例如,如果我通过linqpad使用它,就没有问题。我应该指出,assessmentContent()可以命名为'getAssessmentContent()‘。
,这是我的部分视图控制器,以及一些相关代码:
public class ContentsModel {
public int? assessmentId { get; set; }
public List<short> comparison { get; set; }
}
public class ContentsController : Controller {
public static string nl = System.Environment.NewLine;
public ActionResult ContentsView(int assessmentId) {
ViewBag.DebugInfo = new List<string>();
var vm = new ContentsModel();
vm.assessmentId = assessmentId;
vm.comparison = reval.ach.assessmentContent(assessmentId).ToList();
return View("~/Views/ach/Contents/ContentsView.cshtml", vm);
}
public ActionResult update(ContentsModel vm) {
ViewBag.DebugInfo = new List<string>();
sqlFetch();
ViewBag.DebugInfo.Add($"VM Pased In {vm.assessmentId} c{vm.comparison.intsJoin()}");
sqlFetch();
var crud = new crud.ach.assessmentContent((int)vm.assessmentId);
ViewBag.DebugInfo.Add($"newly fetched CRUD {crud.assessmentId} b{crud.baseline.intsJoin()} c{crud.comparison.intsJoin()}");
sqlFetch();
crud.comparison = vm.comparison;
ViewBag.DebugInfo.Add($"CRUD after crud_comparison = vm_comparison {crud.assessmentId} b{crud.baseline.intsJoin()} c{crud.comparison.intsJoin()}");
sqlFetch();
crud.saveTheData();
ViewBag.DebugInfo.Add($"CRUD after save {crud.assessmentId} b{crud.baseline.intsJoin()} c{crud.comparison.intsJoin()}");
sqlFetch();
vm.comparison = crud.comparison;
ViewBag.DebugInfo.Add($"VM after vm_comparison = crud_comparison {vm.assessmentId} c{vm.comparison.intsJoin()}");
sqlFetch();
return PartialView("~/Views/ach/Contents/ContentsView.cshtml", vm);
}
void sqlFetch() {
ViewBag.DebugInfo.Add(
"SQL Fetch " +
Sql.ExecuteOneColumn<short>("select contentId from ach.assessmentContent where assessmentId = 12", connections.research).intsJoin()
);
}
}
public static partial class extensions {
public static string intsJoin(this IEnumerable<short> ints) {
var strings = new List<string>();
foreach (int i in ints)
strings.Add(i.ToString());
return string.Join(",", strings);
}
}我知道,我可能没有3层体系结构或模型-视图-控制器结构最好在这里实现。
您会注意到,在我的绝望中,我在模型更改的每一个点都直接检查了数据库表。
部分视图:
@model reval.Views.ach.Contents.ContentsModel
@using reval
@{Layout = "";}
<div id="contentDiv">
<form id="contentForm">
@Html.HiddenFor(m => m.assessmentId)
@Html.ListBoxFor(
m => m.comparison,
new reval.ach.content()
.GetEnumInfo()
.toMultiSelectList(
v => v.Value,
d => d.DisplayName ?? d.Description ?? d.Name,
s => Model.comparison.Contains((short)s.Value)
),
new { id = "contentListBox" }
)
</form>
<br/>
@foreach(string di in ViewBag.DebugInfo) {
@Html.Label(di)
<br/>
}
</div>
<script>
$("#contentListBox").change(function () {
$.ajax({
url: "/Contents/update",
type: "get",
data: $("#contentForm").serialize(),
success: function (result) {
$("#contentDiv").html(result);
},
error: function (request, status, error) {
var wnd = window.open("about:blank", "", "_blank");
wnd.document.write(request.responseText);
}
});
})
</script>,最后是主视图中的调用:
<div id="testDiv">
@if (Model.assessment != null && Model.assessment.assessmentId != null) {
Html.RenderAction("ContentsView", "Contents", new { assessmentId = Model.assessment.assessmentId });
}
</div>发布于 2016-10-19 16:37:46
我讨厌当我解决一个问题的时候,没有确切地确定我为解决问题所做的事情。但是,在处理了上面的一些代码之后,我让它正确和一致地工作了。
然而,我几乎可以肯定,这个问题与asp.net mvc在从服务器传递数据到客户端和向后传递数据时的工作方式产生了误解。也就是说,当服务器上的C#视图模型和控制器的数据被发送到客户机上的html/asp时,它们仍然处于活动状态。我有一种预感,客户端数据与C#对象不一样,但我确实感觉到,ASP.Net MVC正在更新C#对象,以应对回发上的任何更改。现在,我清楚地知道,实际上,C#对象被完全丢弃并完全实例化(调用了构造函数和所有相关的结果),并重新填充了来自客户端的数据。即使客户端没有进行任何更改,这也是正确的。
我认为实际上正在对数据库进行更新。没有出现回滚现象。但是,在重新实例化时发生了一些事情,导致了对数据库的第二次调用,并重新设置了它们的值。这可以解释为什么它在ASP.net MVC之外工作得很好。这就解释了为什么在我意识到这一点之后,我才解决了这个问题。
我认为这一反应是准确的,但不是精确的。我的意思是,我相信指南解决了这个问题,即使它没有确定上面的违规代码的确切行。由于它的准确性,我认为这是公平的游戏标记它作为一个答案。由于不精确,我愿意把别人的反应作为答案,如果他们能更精确。然而,由于上面的代码不再被使用,所以它都是为了学习目的。
发布于 2016-07-21 21:31:35
您是否确定您正在对数据库进行的事务已提交或已完成?可能会有其他交易同时进行,从而回退您正在进行的事务。
https://stackoverflow.com/questions/38514580
复制相似问题