即使使用单个脚本引用,Ajax BeginForm也会发送多个请求

时间:2017-09-09 13:56:37

标签: jquery .net ajax asp.net-mvc

我正在研究.NET ASP.MVC应用程序,在我的一个视图中,我实现了Ajax.BeginForm_Layout.cshtml我已经按顺序添加了两个脚本:

  • <script src="~/Scripts/jquery-3.1.1.js"></script>

  • <script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>

主要的错误是当我使用这个表单时,post请求是多次的,但只是第二次。例如:我正在向数据库添加项目,并通过部分视图在同一站点上显示数据库元素列表。当我第一次使用此表单时,正确添加了项目,但第二次发布请求后,会出现两个相同的项目。我已经阅读了它,原因是当您应用两次脚本引用时,我只在_Layout.cshtml中添加了一次脚本引用。

这是我的观点:

<div id="target">
    @using (Ajax.BeginForm("Add", "Home",
        new AjaxOptions
        {
            HttpMethod = "POST",
            InsertionMode = InsertionMode.Replace,
            UpdateTargetId = "target"

        }))

    {
        @Html.EditorFor(m => m)
        <input type="submit" value="Send" />           
    }

    @Html.Action("List")

</div>

这是我的控制器,它使用List返回部分视图和var:

public ActionResult List()
    {
        ItemContext db = new ItemContext();
        var List = db.Items.SqlQuery("SELECT * FROM dbo.Items");

        return PartialView("List",List);
    }

负责将新项添加到db中的控制器:

[HttpPost]
        public ActionResult Add(Item Item)
        {
            ItemContext db = new ItemContext();
            db.Items.Add(Item);
            db.SaveChanges();


            return View("Index");
        }

1 个答案:

答案 0 :(得分:0)

您当前正在从Add操作方法返回索引视图,该方法将使用它的布局呈现索引视图。生成的html有一个脚本标记,其中包含jquery.unobtrusive-ajax.min.js js文件。因此,将索引视图的结果html注入当前页面的DOM将会将jquery.unobtrusive-ajax.min.js js文件的另一个副本加载到页面。这就是您在第一次提交表单后获得“双重帖子”行为的原因。

解决方案是返回局部视图

[HttpPost]
public ActionResult Add(Item item)
{
    var db = new ItemContext();
    db.Items.Add(item);
    db.SaveChanges();

    //Get the items again and pass tot he partial view to render the list
    var itemList = db.Items.ToList();
    return PartialView("List", itemList);
}

现在,由于您只返回项目列表的部分视图,因此您需要更新主视图,以便UpdateTargetId只是列表的容器div,而不是整个表单。

@using (Ajax.BeginForm("Add", "Home",
                            new AjaxOptions
                            {
                                HttpMethod = "POST",
                                InsertionMode = InsertionMode.Replace,
                                UpdateTargetId = "target"

                            }))

{
    @Html.EditorFor(m => m)
    <input type="submit" value="Send" />
}
<div id="target">
    @Html.Action("List")
</div>