Raza Ali Raza Ali - 3 months ago 49
Ajax Question

Send exception message in Ajax.BeginForm MVC 4 scenario

I have a partial view that contains an ajax form. The view simply adds and updates user information.

The controller sends the same partial view back as ActionResult.

What I want to do is to display an error message if the transaction was not successful. But it should still send back the partial view, only this time with a message.

How would this be achieved?

Code:

ManageUsers.cshtml

<div id="details">
@{
Html.RenderPartial("AddModifyUserPartialView");
}
</div>

@{
Html.RenderPartial("ListUsersPartialView");
}


AddModifyUserPartialView.cshtml

@using (Ajax.BeginForm("AddModifyUser", "Account", FormMethod.Post,
new AjaxOptions()
{
UpdateTargetId = "details",
OnFailure= "handleError",
OnSuccess="handleSuccess"
},
new { id = "useragentform",
enctype = "multipart/form-data" }))
{
//form fields here
<input type="submit" id="savebutton" name="savebutton" value="Add New User" />
}


Also in the partial view:

function handleError(ajaxContext) {

var response = ajaxContext.get_response();
var statusCode = response.get_statusCode();

alert(statusCode);
}


Account Controller

try
{
SecurityManager.AddUpdateUserAgent(ua);
}
catch (Exception ex)
{
//how do I send the message back along with the partial view???
}
return PartialView("AddModifyUserPartialView");

Answer

Two parts to solving this, create a new exception, let's call it StatusException, with your message, and throw it when you've caught the normal exception:

try
{
   SecurityManager.AddUpdateUserAgent(ua);
}
catch (Exception ex)
{
   throw new StatusException("Your error message here")
} 
return PartialView("AddModifyUserPartialView");

Override Controller::OnException and handle the exception by setting it to handled, setting the error code to 500, setting the HttpContext.Response.StatusDescription to your StatusException message. For example:

    protected override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.Exception == null) return;

        Type exceptionType = filterContext.Exception.GetType();

        if (exceptionType == typeof(StatusException))
        {

            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.ContentEncoding = Encoding.UTF8;
            filterContext.HttpContext.Response.HeaderEncoding = Encoding.UTF8;
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            filterContext.HttpContext.Response.StatusCode = 500;
            filterContext.HttpContext.Response.StatusDescription = filterContext.Exception.Message;
        }
     }

Then, in your OnFailure handler for Ajax.BeginForm, display out the error parameter:

function handleError(data){
    //display data.errorThrown, data.statusCode, etc...
}

By setting the error code to 500 in the OnException override, AjaxForm will detect an error and jump into your handler. We set the StatusDescription in the override as well, so that message will be available in the handleError callback.