FBryant87
FBryant87

Reputation: 4595

MVC - PartialView not updated after Ajax POST

Within this application I've been given to work with, a partial view 'MessageForm' has a simple Ajax form like so:

@using (Ajax.BeginForm("", "", new AjaxOptions { HttpMethod = "POST" }, new { id = "addForm", enctype = "multipart/form-data" }))
{
    @Html.LabelFor(model => model.Message) //displays "Hello"
}

When the form is submitted, the ChangeMessage function on the controller is called:

$('#addForm').submit(function () {
    var formdata = new FormData(document.forms.namedItem("addForm")); 
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '@Url.Action("ChangeMessage")');
    xhr.send(formdata);
    return false;
});

This ChangeMessage() method simply modifies the Message property in the model, and returns the same partial view again:

[HttpPost]
[ValidateAntiForgeryToken]
public PartialViewResult ChangeMessage(MessageModel model)
{
    model.Message = "Goodbye";
    return PartialView("MessageForm", model);
}

The message is updated to "Goodbye" in the model correctly (I've debugged the view), but it is not displayed in the output, the output HTML still shows "Hello" when the view is returned. The following line within the form is still outputting this old message:

@Html.LabelFor(model => model.Message) //correct when debugged as "Goodbye", but still displaying "Hello" in the browser

It's as if the view has been rendered again, but with no actual output.

Very new to Ajax, so it's most likely I've misunderstood something here?

Upvotes: 2

Views: 1751

Answers (1)

Richard
Richard

Reputation: 30618

The Ajax.BeginForm helper is part of the Microsoft Unobtrusive Ajax library, but you're not using it completely. Ensure you've done the following:

  1. Add the Javascript library: Install-Package Microsoft.jQuery.Unobtrusive.Ajax
  2. Ensure the jquery.unobtrusive-ajax.js file is referenced by your layout

With the @Ajax.BeginForm, you need to specify an AjaxOptions telling it what to do with the response. In your case, I suspect you want to replace the contents of the form with the result:

<div id="myform">
    @using (Ajax.BeginForm("ChangeMessage", new AjaxOptions { UpdateTargetId = "myform" }))
    {
        @Html.EditorFor(m => m.Message)
        <input type="submit" />
    }
</div>

You don't need your Javascript for submitting the form using jquery - the unobtrusive library does this for you.

Finally, you need to modify your ChangeMessage view as LabelFor will only display the field name, not the contents of the model.

Upvotes: 3

Related Questions