ASP.NET Web API: Non-descriptive 500 Internal Server Error
Exception Handlingasp.net Web-ApiException Handling Problem Overview
As title says, I’ve got 500 Internal Server Error from GET request to an IQueryable action. The body of the error is empty. That error happens after my action returns result.
I use ASP.NET Web API RC.
How can I get stack trace of that error?
Exception Handling Solutions
Solution 1 - Exception Handling
You can try adding:
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy =
IncludeErrorDetailPolicy.Always;
to your Application_Start()
in the Global.asax. This solution works for many of the common errors.
If, however, you aren't getting satisfactory information you should consider writing an l Exception Filter and registering it globally.
This article should get you started. The core of what you need is to write & register something like:
public class NotImplExceptionFilter : ExceptionFilterAttribute {
public override void OnException(HttpActionExecutedContext context) {
if (context.Exception is NotImplementedException) {
context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
}
}
}
Solution 2 - Exception Handling
Post RC, this issue was fixed and you will be getting error details also apart from the 500 Internal Server Error. (This issue is fixed for Web Host scenarios only though).
You could do the following to get the details of the actual exception which might be occurring during a formatter's WriteToStream method.
ObjectContent<IEnumerable<Product>> responseContent = new ObjectContent<IEnumerable<Product>>(db.Products.Include(p => p.ProductSubcategory).AsEnumerable(), new XmlMediaTypeFormatter()); // change the formatters accordingly
MemoryStream ms = new MemoryStream();
// This line would cause the formatter's WriteToStream method to be invoked.
// Any exceptions during WriteToStream would be thrown as part of this call
responseContent.CopyToAsync(ms).Wait();
Solution 3 - Exception Handling
I ran into this same issue. I found Kiran Challa's response helpful in getting the actual exception being thrown outside of my action.
To solve my issue, setting the ProxyCreationEnabled property of my context to false got me a step further.
In my scenario, my next exception was due to a circular reference in my models. After cleaning that up, the phantom 500 response was gone. Good luck if you haven't solved this yet!
Solution 4 - Exception Handling
A deceivingly simple routing weakness caused this problem in my case: There was another HttpPost with the same signature (not name) in my Api Controller. The default routing did not resolve the name differences, and the ServiceError 500 was the response it gave before either of the Api functions were reached. Solution: change the default routing or your signatures and try again.
Here is my RouteConfig.cs that works quite well for standard WebApi2 usage:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// Default is required in any case.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Solution 5 - Exception Handling
This may be related to circular reference.
Try adding the following code to Application_Start method in the Global.asax file:
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
Solution 6 - Exception Handling
I had the issue in RC when I was not specifying query parameters in the right order. For example, if you specify $skip=0
, it will get 500, but if you specify $orderby=xxx&skip=0
no error.
Solution 7 - Exception Handling
This Scenario was caused for the following reasons
-
The problem occurred due to misformed Web.config. ( Multiple configSections)
-
Instead of creating roslyn folder inside bin folder, I had it created at the root. (Deployment location.)
The best way to diagnose this was, to put a simple HTML page at the application location and try to browse it. 500 Error description will be displayed on this html page.
And also don't forget to add
> <customErrors mode="Off"></customErrors>
to Web.config
Solution 8 - Exception Handling
I usually use the Global.asax to catch all error. Here is a code snip you can use
public void Application_Error(object sender, EventArgs e)
{
Exception exc = Server.GetLastError();
MvcApplication mvcApplication = sender as MvcApplication;
HttpRequest request = null;
if (mvcApplication != null) request = mvcApplication.Request;
}
Solution 9 - Exception Handling
I had the same problem, but the source of it was slightly different:
I set the CORS
policy incorrectly and that gives me 500 Internal server error
, but since CORS
was not working, the Access-Control-Allow-Origin
header was not presented in response and browser can't read the actual response
I solved it with ChromeDevTools option Copy as cURL
which allows me see the response and understand the source of error
Solution 10 - Exception Handling
Fredrik Normén wrote a great blog post called ASP.NET Web API Exception Handling about that topic. His solution uses custom exception classes and an exception filter attribute that can be applied to all ApiController
action methods.