【问题标题】:JQuery AJAX Post to Controller data incorrectJQuery AJAX 发布到控制器数据不正确
【发布时间】:2013-11-27 18:34:49
【问题描述】:

这是我想要做的:

我的目标是在页面加载时显示来自页面模型的 Trending Opinions(自定义模型)列表。如果用户单击“显示更多趋势意见”按钮,它会使用 ajax 调用控制器上的方法,然后检索额外数量的项目,返回页面并显示它们。然后它又增加了20个。然后他们可以重复该过程并再次单击它,等等。

当您在项目列表上单击“显示更多”时,与普通网站完全相同。

如果我处理此问题的方式不正确,并且您知道任何教程(或只是在您的脑海中)显示在 MVC 4 中执行此操作的正确方法,请告诉我。我目前的做法并没有死心塌地,这只是我找到的“最正确”的方式。


我关注了一个类似问题的答案:How to Update List<Model> with jQuery in MVC 4

但是,通过我的控制器的数据不正确,我无法弄清楚问题所在。

让我尽可能多地提供信息,因为我不知道错误可能出在哪里。

页面模型(OpinionModel 有一些公共属性):

 public class IndexModel
{
      public IList<OpinionModel> TopTrendingOpinions { get; set; }
}

观点:

<div id="TrendingOpinions">

            <p>What is trending at the moment</p>

            @using (Html.BeginForm("LoadMoreTrendingOpinions", "AjaxHelper",
             method: FormMethod.Post,
             htmlAttributes: new { @class = "form-horizontal", id = "LoadTrendingOpinionsForm" }))
         {
            @Html.EditorFor(x => x.TopTrendingOpinions)
            <input type="submit" value="Load More Trending Opinions" />  
         }

        <script type="text/javascript">
            $('#LoadTrendingOpinionsForm').submit(function () {
                   $.ajax({
                        url: this.action,
                        type: this.method,
                        data: {
                            topTrendingOpinions: $(this).serialize()
                        },
                        success: function (result) {
                            alert(result);
                        }
                    });

                return false;
            });
</script>
</div>

**我的模型还有一个 EditorTemplate。

控制器:**

   [HttpPost]
    public ActionResult LoadMoreTrendingOpinions(IList<MyGoldOpinionMVC.Models.OpinionModel> topTrendingOpinions)
    {
       var dataHelper = new Data.DataHelper();
        var moreTrendingOpinions = dataHelper.LoadMoreTrendingOpinions(topTrendingOpinions.LastOrDefault().Id);

       // var partialView = PartialView("../PartialViews/_ListOfPostedOpinion", moreTrendingOpinions);
        return View(moreTrendingOpinions);
    }

所以这里是事件的顺序: 运行站点时,表单会显示 OpinionModel 列表(使用显示正确数据的编辑器模板)。当我单击 SUBMIT 按钮时,它转到控制器(我有一个断点),“topTrendingOpinions”参数的数据是一个列表,其中包含一个项目,但该项目为空。所以换句话说,它没有通过明显用于填充表单的列表。

【问题讨论】:

    标签: ajax list asp.net-mvc-4 controller


    【解决方案1】:

    我能够将列表发回控制器的唯一方法是使用 jquery 手动构建它。我的理解是 this.serialize 在表单上单击将尝试序列化整个会变得非常难看。我会怎么做是

    <input type="button" class="btnMore" value="Load More Trending Opinions" /> 
    
    $('.btnMore').on('click', function () {
               $.ajax({
                    url: '@Url.Action("LoadMoreTrendingOpinions", "AjaxHelper")',
                    type: 'post',
                    contentType: 'application/json; charset=utf-8',
                    data: {
                        Id: '@ViewBag.Id'
                    },
                    success: function (result) {
                        //add results to your table
                    }
                });
        });
    

    并设置通过控制器上的视图包发送的最后一条记录的 id,以便您有一个参考来拉下一个块。如果您有任何问题,请告诉我

    【讨论】:

    • 我喜欢你的想法,并且在一定程度上让它发挥了作用。它适用于我在最初加载页面时设置的 ViewBag Id,但是在我对控制器的 ajax 调用中,我尝试将 Id 设置为新 Id,但它从未将其保存在 View 上,并且下一个 ajax 调用只是使用最初设置的 ID。
    • 在这种情况下,我会将 Id 保存到表单上的隐藏字段而不是视图包中,看看是否有帮助
    • 你的意思是在第一个成功返回之后再做一个ajax调用吗?我正在返回一个包含新项目列表的 PartialView,因此它不允许我从第一个 ajax 调用中获取 Id。
    • 您可以将 ID 添加到要传递给部分的模型中并以这种方式设置隐藏字段吗?
    【解决方案2】:

    发布列表时,您必须非常小心您的输入名称是否正确。如果不是,则默认模型绑定器在发布时无法将它们解析为类,从而导致控制器中的对象为空。

    在您的情况下,您发布的是模型内的模型列表,而不是整个模型。我会使用 PartialView 而不是 editortemplate,只是为了更轻松地处理字段名称。在我的示例中,我们发布了 IndexModel 中包含的 FooModel 列表

    型号

    public class FooModel
    {
        public string Foo { get; set; }
        public string Bar { get; set; }
    }
    public class IndexModel
    {
        public IList<FooModel> Foos { get; set; }
    }
    

    查看

    @using (Html.BeginForm("LoadMoreTrendingOpinions","AjaxHelper",
             method: FormMethod.Post,
             htmlAttributes: new { @class = "form-horizontal", id = "LoadTrendingOpinionsForm" }))
         {
            @Html.Partial("FooModelsPartial", Model.Foos)
            <input type="submit" value="Load More Trending Opinions" />  
         }
    

    FooModels部分

    @model IList<FooModel>
    
    @for (int i = 0; i < Model.Count(); i++)
    {
        @Html.EditorFor(model => model[i].Foo)
        @Html.EditorFor(model => model[i].Bar)
    }
    

    注意我们如何使用 for 而不是 foreach 循环。这是因为 foreach 循环中的编辑器没有正确命名。在这种情况下,我们希望我们的字段为 [0].Foo、[0].Bar、[1].Foo、[1]。酒吧等

    控制器:

        [HttpPost]
        public ActionResult LoadMoreTrendingOpinions(IList<FooModel> topTrendingOpinions)
        {
            // do something with toptrending thingy
    
            var model = new IndexModel();
            model.Foos = topTrendingOpinions;
    
            return View("Index", model);
        }
    

    现在,我认为真正的问题是,您真的想发布整个模型列表以获取与其中一个相关的一堆新模型吗?发布您想阅读更多的意见 id,返回包含请求的更多趋势意见的部分视图并使用 jquery 将其附加到视图中的某个元素,不是更方便吗?

    HTML:

    @using (Html.BeginForm("LoadMoreTrendingOpinions","AjaxHelper",
             method: FormMethod.Post,
             htmlAttributes: new { @class = "form-horizontal", id = "LoadTrendingOpinionsForm" }))
         {
            <div id="more">@Html.Partial("FooModelsPartial", Model.Foos)</div>
            <input type="submit" value="Load More Trending Opinions" />  
         }
    

    Javascript:

     $('#LoadTrendingOpinionsForm').submit(function () {
                   $.ajax({
                        url: this.action,
                        type: this.method,
                        data: {
                            id: 1 /* The id of trending item you want to read more of */
                        },
                        success: function (result) {
                            $("#more").html(result)
                        }
                    });
    
                return false;
            });
    

    控制器:

        [HttpPost]
        public ActionResult LoadMoreTrendingOpinions(int id)
        {
            var moreTrendingOpinions = dataHelper.LoadMoreTrendingOpinions(id);
    
            return PartialView("FooModelsPartial", moreTrendingOpinions);
        }
    

    【讨论】:

    • 关于你的问题,我宁愿只发布一个 ID,然后返回另一块结果。我遇到的问题是每次都维护最后一个 ID。我尝试使用 ViewBag,但它似乎没有从返回的块中保存最新的项目(所以我知道下次单击“更多”时从哪里开始)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    相关资源
    最近更新 更多