【问题标题】:Ajax call returning old ASP.NET MVC partial view instead of updated viewAjax 调用返回旧的 ASP.NET MVC 部分视图而不是更新的视图
【发布时间】:2021-06-18 08:38:12
【问题描述】:

我有一个由按钮触发的 Ajax 调用,它调用控制器来更新局部视图。控制器返回一个更新后的局部视图,但是在 Ajax 调用的成功函数中接收到的局部视图是原始视图,而不是更新后的视图。

我创建了一个示例 ASP.NET MVC 程序来重现该问题。该程序在表格中显示客户列表,如下所示。

Snapshot of UI

文本框在局部视图_Status 中呈现。单击 Toggle Status 按钮时,通过 Ajax 调用控制器以在真假之间切换客户的状态,并刷新相应文本框的局部视图。问题是状态永远不会改变。这是为什么呢?

更新

我刚刚在控制器的Status动作中添加了以下代码行,现在,Ajax成功函数正确接收到更新的局部视图!

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; }
        }
    }
}

谢谢!

【问题讨论】:

  • 嗨,我可能完全错了,但是,我认为您错过了在表格中为 tr 添加id 即:@foreach (var summary in Model){ &lt;tr&gt;$('#' + id).replaceWith(partialView);?
  • 局部视图渲染一个。 id 是 . 的 id
  • 我认为 和 $('#' + id).replaceWith(partialView); 不匹配.应该是 $('#S' + id).replaceWith(partialView);
  • 如果你看一下按钮定义,你会看到 updatePartialView() 函数是用 this.name == @("S" + summary.Input.Number) 调用的,也就是id .
  • 真正的问题是,当我在调试器中查看 Ajax 成功函数的 partialView 参数时,这不是更新后的局部视图。然而,控制器被正确调用,局部视图被正确调用,切换状态。

标签: ajax asp.net-mvc asp.net-ajax partial-views asp.net-mvc-partialview


【解决方案1】:

这是Asp.net MVC ModelState.Clear 的副本。

在当前场景下,因为没有验证status字段,所以清除ModelState就ok了。但是,MVC 的正确方法是向控制器中的 GET 操作传递一个状态值(true 或 false),切换该值,返回结果字符串,然后更新页面上的文本框。

【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多
    热门标签