MVC4 Ajax.BeginForm没有替换UpdateTargetId

时间:2013-02-26 17:50:27

标签: c# ajax asp.net-mvc-4 ajax.beginform razor-2

关于Ajax.BeginForm的问题,有很多关于使用返回局部视图正确更新目标元素的问题: mvc4 ajax updating same page
ASP.NET MVC 4 - Ajax.BeginForm and html5
MVC 4 (razor) - Controller is returning a partialview but entire page is being updated
MVC 4 Ajax is not updating the PartialView within the page
但是,所有这些都可以通过手动写出jQuery ajax或包含丢失的javascript文件来解决。

  @using (Ajax.BeginForm("PostcardDetails", new AjaxOptions()
  {
    InsertionMode = InsertionMode.Replace,
    UpdateTargetId = "details"
  }))
  {
    <div id="PostcardSearchResults">
      @{Html.RenderAction("PostcardSearchResults", Model);}
    </div>
  }
  <div id="details">
  </div>

相关控制器代码:

[AcceptVerbs(HttpVerbs.Post | HttpVerbs.Get)]
public ActionResult PostcardSearchResults(PostcardSearchFilter filter)
{
        PostcardSearchResults model = new PostcardSearchResults(filter);
        return PartialView("_PostcardSearchResults", model);
}

在我的布局中,我引用了这些jQuery文件。此外,我已经验证页面正在输出正确的路径,并且它找到了正确的文件。我尝试切换unobtrusive-ajax.min.jsvalidate.min.js的顺序,但没有成功。

<script type="text/javascript" src="@Url.Content("~/Scripts/globalize.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.9.1.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-ui-1.10.0.custom.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></script>

此外,在我的网站的根web.config和我的View文件夹中的web.config中,我已经包含:

<add key="webpages:Version" value="2.0.0.0"/>
<add key="PreserveLoginUrl" value="true"/>
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>

我不知道还有什么地方可以看。没有抛出javascript错误,控制器被正确命中,返回PartialViewResult。 HTML中的Form元素填充了所有正确的data-属性。

12 个答案:

答案 0 :(得分:13)

jquery.unobtrusive-ajax.min和JQuery 1.9存在问题,因为JQuery 1.9不支持任何more的live()方法。所以你应该使用JQuery migrate插件,并引用JQuery migrate js。

答案 1 :(得分:4)

确保将unobtrusive-ajax.js包含在您放置了ajax表单的页面中。

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

答案 2 :(得分:2)

我遇到了这个问题,我刚从NuGet安装了最新的不显眼的软件包并解决了问题

PM&GT;安装包Microsoft.jQuery.Unobtrusive.Ajax

需要JQ 1.8 +

答案 3 :(得分:1)

我遇到了类似的问题 - 我已将所有脚本捆绑并正确加载,并且所有代码都已正确实现。我检查了包管理器以查看是否需要更新任何脚本以及jQuery和jquery.unobtrusive-ajax。 jQuery从1.9升到1.9.1。当我重建我的解决方案时,目标DIV已成功更新。尝试并更新解决方案中的所有JS,它可能会有效。

答案 4 :(得分:1)

以下内容需要在任何使用ajax的页面上。

@section Script {
    @Scripts.Render("~/bundles/jqueryval")
}

答案 5 :(得分:1)

我不知道是否有其他人会碰到这个,但在我的情况下,它似乎只是没有更新。我正在构建一个简单的编辑表单,您可以从下拉列表中选择要编辑的项目,单击按钮,AJAX会为所选项目加载编辑表单。

它第一次工作,但在更改我在下拉列表中的选择并单击按钮后,没有任何表单值发生更改,即使我验证了我的服务器端代码是将新项目加载到视图模型中。所以看来替换不起作用。在单步执行jquery.unobtrisive-ajax.js之后,我发现替换了我的目标元素的内容,只是使用了已经拥有的相同视图标记,这与传递的模型不匹配观点!

当我意识到这是ModelState让我感到高兴的时候。我第二次点击加载按钮,它提交了我的下拉选择,但也提交了我填写的编辑表单。编辑表单中的所有值都已添加到ModelState(如您所料)。然后,我的控制器代码将所提交的视图模型(从编辑表单值创建的模型绑定器)替换为所选下拉值的视图模型,并将其传递给局部视图。但是,局部视图使用了一堆Html.[X]For辅助方法。这些忽略更新的视图模型并直接从ModelState中提取它们的值。例如:

@Html.DisplayFor(m => m.Name)
@Model.Name

会为Name显示两个不同的值;前者显示提交的名称,后者显示更新的名称。这是允许MVC在(服务器端)验证错误之后记住用户的表单条目的机制。在这种情况下,因为这是部分页面加载而我只丢弃所有提交的值,所以我不需要任何ModelState值,因此我只需在返回之前调用ModelState.Clear()查看更新的视图模型。

    public ActionResult GetItemEditForm(EditItemsViewModel editItemsVM)
    {
        if (editItemsVM.SelectedItemID != null)
        {
            //Load the selected item
            ItemsModelManager.GetEditItemsVM(editItemsVM);

            //Clear the submitted form values
            ModelState.Clear();
        }

        return PartialView("_ItemsEditor", editItemsVM);
    }

答案 6 :(得分:1)

哇,这里有很多答案。我的问题是由于一个自举面板。它正在创建一个嵌套的#34;面板。我删除了面板标记,只使用了一个普通的旧div,它起作用了。我认为UpdateTargetId必须是AJAX表单的直接父级。

这是说明问题的html。

<div class="panel panel-default" id="notes-form">
  <div class="panel-body">
    @using (Ajax.BeginForm("EditNote", new { id = Model.Id }, new AjaxOptions { UpdateTargetId = "notes-form" }, htmlAttributes: new { @class = "form-horizontal" }))
    {
    }
  </div>
</div>

答案 7 :(得分:0)

对于那些需要更多解释的人......

在程序包管理器控制台PM中键入此内容&gt; Install-Package jQuery.Migrate

在您的部分视图中引用它:

script src =&#34;〜/ Scripts / jquery.unobtrusive-ajax.js&#34;&gt;

  

快乐编码所有人。

答案 8 :(得分:0)

用户xr280xr的答案包括

ModelState.Clear();

为我工作。我正在使用的应用程序是在较旧的jQ(1.7.x)上,因此迁移在我们的情况下不起作用。清除控制器中的模型状态完全符合我们对BeginForm的预期。

答案 9 :(得分:0)

检查母版页或您的页面的脚本参考 jquery.unobtrusive-ajax.js 如果没有添加关于这个js的参考:jquery.unobtrusive-ajax.js

答案 10 :(得分:0)

live()方法在jQuery 1.7版中已弃用,在1.9版中已删除。请改用on()方法。有关详细信息,请参阅:http://www.w3schools.com/jquery/event_live.asp

答案 11 :(得分:0)

首先,从NuGet Manager安装' Microsoft.JQuery.Unobtrusive.Ajax ',稍后再加上“ 〜/ Scripts / jquery.unobtrusive 在包含“ jquery- {version} .js ”之后的“ BundleConfig”中;看起来与此类似:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                "~/Scripts/jquery-{version}.js",
                "~/Scripts/jquery.unobtrusive*));