Ajax 调用返回旧 ASP.NET MVC 部分视图而不是更新视图
Ajax call returning old ASP.NET MVC partial view instead of updated view
我有一个由按钮触发的 Ajax 调用,它调用控制器来更新局部视图。控制器returns更新的局部视图,但是Ajax调用成功函数中收到的局部视图是原始视图,不是更新视图。
我创建了一个示例 ASP.NET MVC 程序来重现该问题。该程序在 table 中显示客户列表,如下所示。
Snapshot of UI
文本框在局部视图_Status 中呈现。当点击 Toggle Status 按钮时,通过 Ajax 调用控制器在 true 和 false 之间切换客户的状态,并刷新相应文本框的部分视图。问题是状态永远不会改变。这是为什么?
更新
我刚刚在控制器的 Status 动作中添加了以下代码行,现在,Ajax success 函数正确接收了更新后的局部视图!
this.ModelState.Clear();
谁能解释一下为什么?
这是显示初始视图的 Index.cshtml 视图。
@model IEnumerable<ComboModel.Models.CustomerSummary>
<script type="text/javascript">
function updatePartialView(id) {
debugger;
$.ajax({
url: "/CustomerSummary/Status",
data: $('#' + id + ' :input').serialize(),
dataType: "HTML",
type: "POST",
success: function (partialView) {
// Here the received partial view is not the one created in
// the controller, but the original view. Why is that?
debugger;
$('#' + id).replaceWith(partialView);
},
error: function (err) {
debugger;
},
failure: function (err) {
debugger;
}
});
}
</script>
<h2>Customer Summary</h2>
<table>
<tr>
<th>Name</th>
<th>Active?</th>
<th>Toggle</th>
</tr>
@foreach (var summary in Model)
{
<tr>
<td>@summary.FirstName @summary.LastName</td>
@Html.Partial("_Status", summary.Input)
<td><button type="button" name="@("S" + summary.Input.Number)" onclick="updatePartialView(this.name)">Toggle Status</button></td>
</tr>
}
</table>
_Status.cshtml局部视图。
@model ComboModel.Models.CustomerSummary.CustomerSummaryInput
<td id="@("S" + Model.Number)">
@Html.TextBoxFor(model => model.Active)
<input type="hidden" value="@Model.Number" name="Number" />
</td>
CustomerSummaryController.cs.
using System.Collections.Generic;
using System.Web.Mvc;
using ComboModel.Models;
namespace ComboModel.Controllers
{
public class CustomerSummaryController : Controller
{
private readonly CustomerSummaries _customerSummaries = new CustomerSummaries();
public ViewResult Index()
{
IEnumerable<CustomerSummary> summaries = _customerSummaries.GetAll();
return View(summaries);
}
public PartialViewResult Status(CustomerSummary.CustomerSummaryInput input)
{
this.ModelState.Clear(); // If I add this, things work. Why?
input.Active = input.Active == "true" ? "false" : "true";
return PartialView("_Status", input);
}
}
public class CustomerSummaries
{
public IEnumerable<CustomerSummary> GetAll()
{
return new[]
{
new CustomerSummary
{
Input = new CustomerSummary.CustomerSummaryInput {Active = "true", Number = 0},
FirstName = "John",
LastName = "Smith"
},
new CustomerSummary
{
Input = new CustomerSummary.CustomerSummaryInput {Active = "false", Number = 1},
FirstName = "Susan",
LastName = "Power"
},
new CustomerSummary
{
Input = new CustomerSummary.CustomerSummaryInput {Active = "true", Number = 2},
FirstName = "Jim",
LastName = "Doe"
},
};
}
}
}
最后,CustomerSummary.cs 模型。
namespace ComboModel.Models
{
public class CustomerSummary
{
public string FirstName { get; set; }
public string LastName { get; set; }
public CustomerSummaryInput Input { get; set; }
public class CustomerSummaryInput
{
public int Number { get; set; }
public string Active { get; set; }
}
}
}
谢谢!
这是 Asp.net MVC ModelState.Clear 的副本。
在当前场景下,由于没有对status字段进行校验,所以清空ModelState就可以了。但是,MVC 的正确方法是将状态值(true 或 false)传递给控制器中的 GET 操作,切换值,return 结果字符串,并更新页面上的文本框。
我有一个由按钮触发的 Ajax 调用,它调用控制器来更新局部视图。控制器returns更新的局部视图,但是Ajax调用成功函数中收到的局部视图是原始视图,不是更新视图。
我创建了一个示例 ASP.NET MVC 程序来重现该问题。该程序在 table 中显示客户列表,如下所示。
Snapshot of UI
文本框在局部视图_Status 中呈现。当点击 Toggle Status 按钮时,通过 Ajax 调用控制器在 true 和 false 之间切换客户的状态,并刷新相应文本框的部分视图。问题是状态永远不会改变。这是为什么?
更新
我刚刚在控制器的 Status 动作中添加了以下代码行,现在,Ajax success 函数正确接收了更新后的局部视图!
this.ModelState.Clear();
谁能解释一下为什么?
这是显示初始视图的 Index.cshtml 视图。
@model IEnumerable<ComboModel.Models.CustomerSummary>
<script type="text/javascript">
function updatePartialView(id) {
debugger;
$.ajax({
url: "/CustomerSummary/Status",
data: $('#' + id + ' :input').serialize(),
dataType: "HTML",
type: "POST",
success: function (partialView) {
// Here the received partial view is not the one created in
// the controller, but the original view. Why is that?
debugger;
$('#' + id).replaceWith(partialView);
},
error: function (err) {
debugger;
},
failure: function (err) {
debugger;
}
});
}
</script>
<h2>Customer Summary</h2>
<table>
<tr>
<th>Name</th>
<th>Active?</th>
<th>Toggle</th>
</tr>
@foreach (var summary in Model)
{
<tr>
<td>@summary.FirstName @summary.LastName</td>
@Html.Partial("_Status", summary.Input)
<td><button type="button" name="@("S" + summary.Input.Number)" onclick="updatePartialView(this.name)">Toggle Status</button></td>
</tr>
}
</table>
_Status.cshtml局部视图。
@model ComboModel.Models.CustomerSummary.CustomerSummaryInput
<td id="@("S" + Model.Number)">
@Html.TextBoxFor(model => model.Active)
<input type="hidden" value="@Model.Number" name="Number" />
</td>
CustomerSummaryController.cs.
using System.Collections.Generic;
using System.Web.Mvc;
using ComboModel.Models;
namespace ComboModel.Controllers
{
public class CustomerSummaryController : Controller
{
private readonly CustomerSummaries _customerSummaries = new CustomerSummaries();
public ViewResult Index()
{
IEnumerable<CustomerSummary> summaries = _customerSummaries.GetAll();
return View(summaries);
}
public PartialViewResult Status(CustomerSummary.CustomerSummaryInput input)
{
this.ModelState.Clear(); // If I add this, things work. Why?
input.Active = input.Active == "true" ? "false" : "true";
return PartialView("_Status", input);
}
}
public class CustomerSummaries
{
public IEnumerable<CustomerSummary> GetAll()
{
return new[]
{
new CustomerSummary
{
Input = new CustomerSummary.CustomerSummaryInput {Active = "true", Number = 0},
FirstName = "John",
LastName = "Smith"
},
new CustomerSummary
{
Input = new CustomerSummary.CustomerSummaryInput {Active = "false", Number = 1},
FirstName = "Susan",
LastName = "Power"
},
new CustomerSummary
{
Input = new CustomerSummary.CustomerSummaryInput {Active = "true", Number = 2},
FirstName = "Jim",
LastName = "Doe"
},
};
}
}
}
最后,CustomerSummary.cs 模型。
namespace ComboModel.Models
{
public class CustomerSummary
{
public string FirstName { get; set; }
public string LastName { get; set; }
public CustomerSummaryInput Input { get; set; }
public class CustomerSummaryInput
{
public int Number { get; set; }
public string Active { get; set; }
}
}
}
谢谢!
这是 Asp.net MVC ModelState.Clear 的副本。
在当前场景下,由于没有对status字段进行校验,所以清空ModelState就可以了。但是,MVC 的正确方法是将状态值(true 或 false)传递给控制器中的 GET 操作,切换值,return 结果字符串,并更新页面上的文本框。