我有一种情况,我使用 Ajax.BeginForm() 将一些数据(评论表单)发布到控制器方法。然后,此控制器方法使用实体框架将一些信息写入数据库(只要 ModelState 有效)。
作为表单的一部分,我使用 OnSucess 重载,在表单发布后执行 javascript 函数。这个函数,基本上调用了另一个控制器方法(它返回一个局部视图——在这种情况下是注释列表)。
我的问题是,新添加的注释不包含在控制器操作返回的视图中,尽管我知道它存在于数据库中。
这使我有两个可能的选择:
- htmlhelper 表单的 OnSucess() 函数在控制器方法实际返回之前执行。
- 实体框架正在处理数据。
在 2 的情况下,我不知道实体框架曾经缓存数据,除非被明确告知这样做。所以我假设它是1。
因此,为了进一步调查,我修改了 OnSucess 方法和控制器操作。
我的表单定义如下:
@using (Ajax.BeginForm("CreateComment", "Home", new AjaxOptions { HttpMethod = "POST", OnSuccess = "something" })){
...
}
我的控制器动作被定义为(为清楚起见省略了细节):
public ActionResult CreateComment(CreateCommentViewModel comment)
{
if (ModelState.IsValid)
{
var context = new myDataContext();
var newComment = new BlogComment
{
BlogID = comment.BlogID,
CommentContent = comment.CommentContent,
CommentDateCreated = DateTime.Now,
CommentDeleted = false,
CommentLive = true,
CommenterEmail = comment.CommenterEmail,
CommenterName = comment.CommenterName
};
var errorList = new List<string>();
context.BlogComments.Add(newComment);
try
{
context.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
errorList.AddRange(from validationErrors in dbEx.EntityValidationErrors from validationError in validationErrors.ValidationErrors select string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage));
}
finally {
return Json(new { result = -2, message = "Error saving to database" }); // Not currently handled client side
}
return Json(new { result = 0, message = "Sucess" });
}else
{
var errorList = (from modelState in ViewData.ModelState.Values from error in modelState.Errors select error.ErrorMessage).ToList();
string message = errorList.Aggregate(string.Empty, (current, errorMessage) => current + (errorMessage + ","));
return Json(new { result = -1, message = message });
}
}
最后,客户端方法定义为:
function something(data) {
switch (data.result) {
case 0:
// Sucess
// Get the Alert
var message = "<strong>Thank You</strong> Your comment has been posted.";
var myAlert = jQuery("#donemessage");
myAlert.html(message);
reloadBlogComments();
break;
case -1:
var errorMessages = data.message.split(',');
var html = "<strong>The following errors were detected:</strong><br/>";
var length = errorMessages.length, element = null;
for (var i = 0; i < length; i++) {
element = errorMessages[i];
// Do something with element i.
html += element + "<br/>";
}
var myErrorAlert = jQuery("#failmessage");
myErrorAlert.html(html);
myErrorAlert.show(500).css("visibility", "visible");
break;
default:
alert(data.message);
break;
}
}
返回值为 0 时,调用函数 reloadBlogComments()。
但是以上的修改,证明了我上面提到的第一个假设(1)实际上是错误的。在控制器返回值之前无法执行成功函数。所以我完全不知道为什么新添加的评论没有与其他评论一起返回。
我的 reloadBlogComments() 函数定义如下:
function reloadBlogComments() {
jQuery.ajax({
// edit to add steve's suggestion.
//url: "/ControllerName/ActionName",
url: '@Url.Action("RenderBlogComments", "Home")',
data: { 'BlogID': '@Model.BlogID' },
success: function (newdata) {
jQuery("#upComments").empty().html(newdata);
},
statusCode: {
404: function (content) { alert('cannot find resource'); },
505: function (content) { alert('internal server error'); }
},
error: function (req, status, errorObj) {
// handle status === "timeout"
// handle other errors
}
});
var myAlert = jQuery("#donemessage");
var myErrorAlert = jQuery("#failmessage");
myErrorAlert.hide(500).css("visibility", "hidden");
myAlert.show(500).css("visibility", "visible");
// Clear the form
jQuery('#CommenterName').val('');
jQuery('#CommenterEmail').val('');
jQuery('#CommentContent').val('');
window.location.hash = '#comments';
}
即使使用延迟调用 reloadBlogComments() setTimeout(function () { reloadBlogComments(); }, 3000);
也无法获得一致的值。
我在哪里错了?