I’m not a fan of the Ajax stuff built into MVC – I much prefer to do it via jQuery – I feel I have more control over everything that is happening.

There are various ways to achieve the same thing but I often use the full “long winded” way of doing it using the $.ajax method over the shorter $.get and $.post functions.

I often need to update the UI depending on the result of the ajax call to the controller so my preferred method is to return a partial view from the controller that I can inject into my page. The partial view is responsible for displaying the appropriate success or fail result.

The Code

This is a basic example to unlock a users account.

jQuery

function AttachUnlockUserClickEvent() {
    $('#btnUnlockUser').unbind().on('click', function () {

        var userId = $('#selectedUserId').val();
        var password = $('#tbUnlockUserNewPassword').val();

        $.ajax({
            url: '@Url.Action("ActionName","ControllerName")',
            cache: false,
            data: { userId: userId, newPassword: password },
            type: 'GET',
            success: function (data) {
                $('#unlockResult').html(data);//this line injects the partial view HTML into the unlockResult div
                //do whatever else you need to…
           },
        });
    });
}

MVC Controller

I create an AjaxResponse object and fill it with messages I want to display to the user, also setting a success/fail stauts.

public async Task UnlockUserAccount(string userId, string newPassword)
{
    AjaxResponse ajaxResponse = new AjaxResponse()
    {
        Status = Utils.Enums.StatusType.Error //default
    };

    var result = DoWhatEverYouNeedToChangeThePasswordAndUnlockAccount();
    if (result.Succeeded)
    {
        ajaxResponse.Status = Utils.Enums.StatusType.Success;
        ajaxResponse.Messages.Add("Password reset successfully.");
        ajaxResponse.Messages.Add("User unlocked.");
    }
    else
    {
        foreach (var error in result.Errors)
        {
            ajaxResponse.Messages.Add(error);
        }
    }    

    return PartialView("_AjaxResponse", ajaxResponse);
}

The above returns a partial view that the jQuery injects into the page to feedback to the user the result.

Partial View

The class of the div and the title is set depending on the status of the model. Then each of the messages in the Model.Messages list is displayed.

@model KpmgMiddleware.ViewModels.AjaxResponse
@model KpmgMiddleware.ViewModels.AjaxResponse

@{
    string title = "";
    string className = "alert alert-dismissible";
    switch (Model.Status)
    {
        case KpmgMiddleware.Utils.Enums.StatusType.Error:
            title = "Error";
            className += " alert-danger";
            break;
        case KpmgMiddleware.Utils.Enums.StatusType.Success:
            className += " alert-success";
            title = "Success";
            break;
        case KpmgMiddleware.Utils.Enums.StatusType.Warning:
            className += " alert-warning";
            title = "Warning";
            break;
    }
}

<p>
    <div class="@className" role="alert">
        <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <strong>@title!</strong>
        @if (Model.Messages.Count > 0)
        {
            <ul>
                @for (int i = 0; i < Model.Messages.Count; i++)
                {
                    <li>@Model.Messages[i]</li>
                }
            </ul>
        }
    </div>
</p>

Partial View Model

This is a very simple view model and it can be expanded to include whatever you need for your UI.

public class AjaxResponse
{
    public StatusType Status { get; set; }
    public List Messages { get; set; }

    public AjaxResponse()
    {
        Messages = new List();
    }
}