MVC4 Ajax.BeginForm not replacing UpdateTargetId

核能气质少年 提交于 2019-12-18 12:18:01

问题


There are so many topics on SO about issues with the Ajax.BeginForm not correctly updating the target element with the return partial view:
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
However, all of these are answered by either manually writing out the jQuery ajax, or including a missing javascript file.

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

Relevant controller code:

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

In my layout, I am referencing these jQuery files. Additionally, I've verified that the page is outputting the proper path, and that it finds the correct files. I've tried switching the ordering of unobtrusive-ajax.min.js and validate.min.js, to no success.

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

Additionally, in my website's root web.config, and the web.config in my View folder, I have included:

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

I'm at a loss for where else to look. There are no javascript errors being thrown, and the controller is being properly hit, returning a PartialViewResult. The Form element in the HTML is populating all the correct data- attributes.


回答1:


There is a problem with jquery.unobtrusive-ajax.min and JQuery 1.9 because JQuery 1.9 doesn't support the live() method any more. So you should use the JQuery migrate plug-in, and reference the JQuery migrate js.




回答2:


Make sure you include the unobtrusive-ajax.js to the page, which you have placed your ajax form.

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



回答3:


I had this problem, I just installed the latest unobtrusive package from NuGet and solved the problem

PM> Install-Package Microsoft.jQuery.Unobtrusive.Ajax

Will need JQ 1.8+




回答4:


I was having similar problems to you - I had all my scripts bundled and loading correctly, and had all code implemented correctly. I checked package manager to see if any scripts needed to be updated and jQuery and jquery.unobtrusive-ajax did. jQuery went from 1.9 to 1.9.1. When I rebuilt my solution the target DIV was updated successfully. Try and update all JS in your solution, it may work.




回答5:


The following needs to be on any page that uses ajax.

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



回答6:


I don't know if anyone else will run into this, but in my case, it only appeared to not be updating. I was building an simple edit form where you select the item you wish to edit from a dropdown, click a button, and it AJAX loads an edit form for the selected item.

It worked the first time, but after changing my selection in the drop down list, and clicking the button, none of the form values changed, even though I verified my server-side code was loading the new item into the view model. So it appeared Replace was not working. After stepping through jquery.unobtrisive-ajax.js, I found that it was replacing the contents of my target element, just with the same view markup it already had, which did not match the model that was passed to the view!

That's when I realized, it was the ModelState that was getting me. The second time I clicked the load button, it submitted my dropdown selection but also my filled out edit form. All of the values in the edit form were added to ModelState (as you would expect). My controller code then replaced the submitted view model (that the model binder created from the edit form values) with the view model for the selected drop down value and passed it to the partial view. However, the partial view uses a bunch of the Html.[X]For helper methods. These ignore the updated view model and pull their values directly from the ModelState. For example:

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

would display two different values for Name; the former displaying the submitted Name and the latter, the updated Name. This is the mechanism that lets MVC remember your user's form entries after a (server-side) validation error. In this case, because this is a partial page load and I'm just throwing out all of the submitted values, I don't need any of the ModelState values so I just call ModelState.Clear() before returning my view for the updated view model.

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



回答7:


Wow, there are a lot of answers here. My problem was due to a bootstrap panel. It was creating a "nested" panel. I removed the panel markup and just used a plain old div and it worked. I think the UpdateTargetId has to be a direct parent of the AJAX form.

Here is the html illustrating the problem.

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



回答8:


For those that need a bit more explanation....

Type this in Package Manager Console PM> Install-Package jQuery.Migrate

Reference this in your partialview:

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

Happy coding everyone.




回答9:


User xr280xr's answer for including

ModelState.Clear();

worked for me. The app I'm working with is on an older jQ (1.7.x) so migrate wouldn't work in our situation. Clearing the model state in the controller did exactly what we expected BeginForm to do.




回答10:


Check The Master Page OR Your Page's Scripts Reference about jquery.unobtrusive-ajax.js if not add Reference about this js :jquery.unobtrusive-ajax.js




回答11:


The live() method was deprecated in jQuery version 1.7, and removed in version 1.9. Use the on() method instead.For more info refer: http://www.w3schools.com/jquery/event_live.asp




回答12:


First, install 'Microsoft.JQuery.Unobtrusive.Ajax' from NuGet Manager and later include "~/Scripts/jquery.unobtrusive" in "BundleConfig" after including "jquery-{version}.js"; which will look something similar to this:

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


来源:https://stackoverflow.com/questions/15095870/mvc4-ajax-beginform-not-replacing-updatetargetid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!