1

I am calling a controller method from the client using jQuery's ajax.

$.ajax({
    url: "/Services/VendorServices.asmx/SendVendorRequestNotifications",
    type: 'POST',
    contentType: "application/json",
    dataType: "json",
    data: JSON.stringify({ vendorModel: info }),
    timeout: requestTimeOut,
    success: function (data) {
        // Success
    },
    error: function (jqXHR, textStatus, errorThrown) {
        // Error: Would like to display meaningful message here!
    }
});

If my SendVendorRequestNotifications throws an exception, I'd like to display an error message on the client side. However, I can't seem to get a good message to display to the user.

textStatus:

error

errorThrown:

Internal Server Error

jqXHR.responseText:

{"Message":"One or more errors occurred.","StackTrace":" at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task'1.GetResultCore(Boolean waitCompletionNotification)
at System.Threading.Tasks.Task'1.get_Result()","ExceptionType":"System.AggregateException"}

As you can see, none of this is useful data. I'd like to be able to gather a more meaningful message on the server and have it available to the error handler of the $.ajax call.

Is this possible?

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • Yes. Have a look at this. Can you show the controller code? May be helpful. https://stackoverflow.com/questions/4707755/asp-net-mvc-ajax-error-handling – mjw Jun 23 '17 at 23:12
  • @mjw: My actual controller has a lot going on. Not sure what would be of interest. The main thing is that I have a `try...catch` block, and my `catch` block logs the error and then rethrows the exception. – Jonathan Wood Jun 23 '17 at 23:15
  • Can you show the stub? The catch block? Those are likely all that is needed to see what's being returned to the client. – mjw Jun 23 '17 at 23:16
  • @mjw: My catch block: `ex = ex.GetInnerMostException(); if (log.IsErrorEnabled) log.ErrorFormat("{0} failed : {1}", nameof(MakeVendorRequests), ex.Message); throw;` – Jonathan Wood Jun 23 '17 at 23:18
  • @mjw: My method stub: `[WebMethod(EnableSession = true)] public async Task MakeVendorRequests(ViperVendorViewModel vendorModel)` – Jonathan Wood Jun 23 '17 at 23:19
  • Have you tried the following from the link in my first comment? `return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Response.ReasonPhrase);` – mjw Jun 23 '17 at 23:20
  • @mjw: Yes, I was able to pass a specific message this way, thanks. The only trouble is that it doesn't call the `error` handler. The message is passed to the `success` handler. That isn't ideal to the way I'm set up. – Jonathan Wood Jun 23 '17 at 23:30
  • Even if you set the `HttpStatusCode` to an error? https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#5xx_Server_error – mjw Jun 23 '17 at 23:34
  • @mjw: I think I see what's happening. First off, this is actually on a web forms site. (Sorry, I have both WebForms and MVC in this project.) My code is `return new JavaScriptSerializer().Serialize(new HttpStatusCodeResult((int)HttpStatusCode.InternalServerError, ex.Message));` But the reason it isn't parsed correctly is because I convert it to a string. But my web method returns a string. So not sure of the best way to handle that. Would you just return an object? – Jonathan Wood Jun 23 '17 at 23:41
  • @mjw: So, returning the object correctly parses the result, but it's still sent to the `success` handler instead of the `error` handler. – Jonathan Wood Jun 23 '17 at 23:45
  • Yes, if you're not returning an `ActionResult` you would need to handle the response manually. Include a `Success = true|false;` in your string response, then add a condition in your success callback. – mjw Jun 23 '17 at 23:45
  • @mjw: Thanks, but I have a lot going on, and it's configured to use the `error` handler. So I can create a response like you say, but would prefer to keep it in the error handler so I don't have to duplicate the error handling code. Perhaps it's just not possible. – Jonathan Wood Jun 23 '17 at 23:47
  • @mjw: Feel free to post a regular answer so I can credit the information you've provided. – Jonathan Wood Jun 23 '17 at 23:48

1 Answers1

1

To manually pass an HttpStatusCodeResult, try this:

return new HttpStatusCodeResult(HttpStatusCode.BadRequest, e.Response.ReasonPhrase);

Unfortunately, it looks like you're locked in to a return type that won't be processed as an AJAX error, so you'll need to consider changing the return type of your controller action to get the desired outcome. Good luck

mjw
  • 1,196
  • 1
  • 12
  • 19