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 结果字符串,并更新页面上的文本框。