MVC 3 + $ .ajax – 响应似乎是从部分视图缓存输出

我一定是想念一些傻瓜,但这就是问题所在。

我在Transactions控制器上有一个Create动作。 Create.cshtml使用jQuery通过调用$ .ajax将表单发布到服务器。 调试显示所有内容都按预期到达服务器。 我使用表单数据来更新记录:这也可以正常工作。 然后我返回一个局部视图,将模型传递给具有默认数据的视图。 我可以调试并validation模型是否传递空值和0,即我的模型的默认数据。

问题是,在响应中发送回浏览器的是旧数据……!

我没有理由看到原因。 希望你能……

注意:我没有使用任何forms的输出缓存。

编辑1:

缓存不会在浏览器中发生。 我说的原因是我可以在Firebug中看到对AjaxCreate Action的调用的响应。 我也可以在Fiddler中看到这一点。

编辑2:

如果查看部分视图的代码,您会看到每个下拉列表或文本框的值都为@ Model.Transaction。[Property]打印在它旁边。 奇怪的是,这显示了正确的值,即我的Transaction对象的默认值,但是下拉列表和文本框坚持使用发布到服务器的值而不是每个应该呈现的属性的默认值。

编辑3:

我已经包含了下面的图像,因此您可以看到打印到每个控件右侧的值。但是控件反映了在之前的$ .ajax调用中发布到服务器的旧数据。 (注释显示创建视图模型时的日期时间,这样我可以看到更新的内容)。

编辑4:

我发现用@ Html.TextBox助手替换@ Html.EditorFor(…)(参见下面的视图代码)可以解决问题。 所以,似乎正在发生的事情是EditorFor助手正在引发问题。 为什么? 我不知道,但会发布另一个更具体的问题。

缓存问题

代码和标记如下:

jQuery的:

$(document).ready(function () { $('input[name="nextRecord"]').live('click', function () { var theForm = $(this).closest('form'); if ((theForm).valid()) { var buttonText = $(this).val(); var action = "/input/Transactions/AjaxCreate/"; if (buttonText === "Reset") { clearForm(theForm); } else { var targetElement = $('#CreateDiv'); var _data = theForm.serialize() + '&nextRecord=' + $(this).val(); $.ajax({ url: action, data: _data, cache: 'false', type: 'POST', dataType: 'html', success: function (html) { $(targetElement).html(html); createDatePickers(targetElement); jQuery.validator.unobtrusive.parse(targetElement); } }); } } return false; }); }); 

部分视图:

 @model FlatAdmin.Domain.ViewModels.TransactionViewModel @* This partial view defines form fields that will appear when creating and editing entities *@ 
Fecha
@Html.EditorFor(model => model.Transaction.TransactionDate, new { @class = "date-picker" }) @Html.ValidationMessageFor(model => model.Transaction.TransactionDate) @Model.Transaction.TransactionDate.ToString()
Origen:
@Html.DropDownListFor(model => model.Transaction.IdFrom, ((IEnumerable)Model.FromAccounts).Select(option => new SelectListItem { Text = (option == null ? "None" : option.AccountName), Value = option.AccountId.ToString(), Selected = (Model != null) && (option.AccountId == Model.Transaction.IdFrom) }), "Choose...") @Html.ValidationMessageFor(model => model.Transaction.IdFrom)@Model.Transaction.IdFrom
Destino:
@Html.DropDownListFor(model => model.Transaction.IdTo, ((IEnumerable)Model.ToAccounts).Select(option => new SelectListItem { Text = (option == null ? "None" : option.AccountName), Value = option.AccountId.ToString(), Selected = (Model != null) && (option.AccountId == Model.Transaction.IdTo) }), "Choose...") @Html.ValidationMessageFor(model => model.Transaction.IdTo)@Model.Transaction.IdTo
Monto
@Html.DropDownListFor(model => model.Transaction.IdCurrency, ((IEnumerable)Model.AllCurrencies).Select(option => new SelectListItem { Text = (option == null ? "None" : option.CurrencyName), Value = option.CurrencyId.ToString(), Selected = (Model != null) && (option.CurrencyId == Model.Transaction.IdCurrency) })) @Html.EditorFor(model => model.Transaction.Amount) @Html.ValidationMessageFor(model => model.Transaction.Amount) @Model.Transaction.Amount
Comentario
@Html.EditorFor(model => model.Transaction.Comment) @Html.ValidationMessageFor(model => model.Transaction.Comment)@Model.Transaction.Comment

视图:

 @model FlatAdmin.Domain.ViewModels.TransactionViewModel @using FlatAdmin.Domain.Entities @{ ViewBag.Title = "Nueva Transaccion"; } 

@ViewBag.Title

@Html.ActionLink("<< Lista de Transacciones", "Index")

@using (Html.BeginForm()) { @Html.ValidationSummary(true)
Elegir Actividad
@Html.DropDownListFor(model => model.Transaction.IdCostCentre, ((IEnumerable)Model.AllCostCentres).Select(option => new SelectListItem { Text = (option == null ? "None" : option.Name), Value = option.CostCentreId.ToString(), Selected = (Model != null) && (option.CostCentreId == Model.Transaction.IdFrom) }), "Actividades...")
Transaccion
@Html.Partial("_Create", Model)

>" />

...o sino, para guardar y volver a la lista de transacciones:

}

控制器动作:

 [HttpPost] public virtual ActionResult AjaxCreate(Transaction transaction) { if (ModelState.IsValid) { service.InsertOrUpdate(transaction); service.Save(); } service.ChosenCostCentreId = transaction.IdCostCentre; TransactionViewModel viewModel = new TransactionViewModel(); viewModel.Transaction = new Transaction(); viewModel.CostCentre = service.ChosenCostCentre; viewModel.AllCostCentres = service.AllCostCentres; viewModel.AllCurrencies = service.AllCurrencies; viewModel.FromAccounts = service.FromAccounts; viewModel.ToAccounts = service.ToAccounts; return PartialView("_Create", viewModel); } 

@Darin Dimitrov在相关主题中提出了答案。

本质上,HtmlHelpers(如Html.EditorFor,Html.TextBoxFor等)首先在ModelState中检查现有值,然后仅在模型中检查。

结果,我需要打电话给:

 ModelState.Clear(); 

无知是如此痛苦。

尝试在控制器操作上明确将outputcache duration设置为0。

我认为浏览器不应该缓存POST,但有时似乎仍然这样做。