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");
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.
The answer above is fine. A simple alternative might be:
if (gotAnError)
{
Response.StatusCode = (int) System.Net.HttpStatusCode.BadRequest; // Or another code
return Json( new { message = "You did something wrong." } );
}
for the (partial) controller, and
function ShowPartialLoadErrors(result) {
var obj = $.parseJSON(response.responseText);
alert(obj.message);
}
for the view.
One could argue that since your request is expecting only a partial view, your action should always return a partial view. If you encounter an error, pass to your view a View Model that is in an error state and let your view render appropriately.
AddUpdateUserVM vm = new AddUpdateUserVM();
try
{
SecurityManager.AddUpdateUserAgent(ua);
}
catch (Exception ex)
{
//log exception
vm.HasError = true;
vm.ErrorMessage = ex.Message;
}
return PartialView("AddModifyUserPartialView", vm);
View:
@if(Model.HasError)
{
<div>@Model.ErrorMessage</div> @* Or whatever you want to display *@
}
@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" />
}
The AjaxOptions' OnFailure function would then only occur if the server can't be reached or responds with some status code other than 200.Personally, I prefer not to use Ajax.BeginForm and to write my own jQuery ajax requests and let the server-side action method return a JSON object containing either an error or the requested view's markup. It gives you complete control over what you return from the server and what you do with it on the client side.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With