ASP.NET MVC AJAX onError handling

2019-08-29 11:25发布

I am trying to delete item from table. There is Ajax link for it.

@Ajax.ActionLink("Delete", "DeleteConfirm", new { id = Model.ID }, new AjaxOptions {
    HttpMethod = "POST", UpdateTargetId = "TableID", OnSuccess = "CloseDialog", OnFailure = "AlerDialog"
  })

It calls DeleteConfirm method from controller with POST method. I made simple controller which should do something so ActionLink should catch error and run OnFailure function (to show alert dialog).

Controller:

public ActionResult DeleteConfirm(int id)
        {            
            // code here
        }

What to return from controller method so OnFailure function invokes?

3条回答
【Aperson】
2楼-- · 2019-08-29 11:42

how about throwing an exception?

public ActionResult DeleteConfirm(int id)
    {
        try
        {
            //make your call to the database here
            return View();
        }
        catch (ExceptionType1 ex)
        {
            //log the details of your error for support purposes, alerting tracing etc. 
            ex.Message = "Nice message for user"
            throw ex;
        }
        catch (ExceptionType2 ex)
        {
            //log the details of your error for support purposes, alerting tracing etc. 
            ex.Message = "Another nice message for user"
            throw ex;
        }
    }

Your ajax call would then know it was a failure, and run the correct function.

Edit I have added a second exception type to satisfy the comments. I still feel this is a good answer, and that the down vote is unfair.

查看更多
相关推荐>>
3楼-- · 2019-08-29 11:46

OnError is fired when error happens on serverside. By error, I mean exception, and I think you can't pass exception message on clientside except of 500 Server error. I think that good aproach is to have some CustomResponse class that your action will return. In your case, something like:

Class DeletionResponse
{
    public bool IsDeletionSuccesfull {get; set; }
    public string Message {get; set;}
}

In DeleteConfirm action you create new response, which maybe needs to inheriteActionResult class(I'm not sure because I'm new to MVC). If some error ocures while deleting, set DeletionSuccesfull to false, and Message to message of exception, or some custom message.

On client side, the point is to examine success in OnSuccess handler, and then decide what to do. Something like:

function handleResponse(deletionResponse){
  if(deletionResponse.d.IsDeletionSuccesfull){
     CloseDialog();
  }
  else{
     AlertDialog(deletionResponse.d.Message);
  }
}
查看更多
老娘就宠你
4楼-- · 2019-08-29 11:46

The OnFailure will fire based off the status code of the result, so something like this would give the desired effect.

return new HttpStatusCodeResult(HttpStatusCode.InternalServerError, "Reason for failure");

Also, not sure if it's related but shouldn't your OnFailure text be "AlertDialog" instead of "AlerDialog"?

EDIT: In your controller action you should be able to test that the request is being made via Ajax by using this Extension method MVC provides Request.IsAjaxRequest(). Note that there is no true way to check if a request is an Ajax request on the server, this method is utilizing the presence of a custom header jQuery sets for all ajax requests it makes, in other words don't use Request.IsAjaxRequest() in business logic.

Source for IsAjaxRequest() method

namespace System.Web.Mvc
{
    public static class AjaxRequestExtensions
    {
        public static bool IsAjaxRequest(this HttpRequestBase request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            return (request["X-Requested-With"] == "XMLHttpRequest") || ((request.Headers != null) && (request.Headers["X-Requested-With"] == "XMLHttpRequest"));
        }
    }
}
查看更多
登录 后发表回答