WebApi's {"message":"an error has occurred"} on IIS7, not in IIS Express

web api example
c# web api
web api vs rest api
web api interview questions
restful web api c#
web api javascript
what is web api and how it works
web api net core

I'm working with ASP.NET MVC 4 WebApi and am having a lot of fun with it running it on my local computer on IIS Express. I've configured IIS Express to serve remote machines too, and so other's in my company are using my computer as our webserver.

After deciding this was a less-than-optimal solution, we decided to put the WebApi on a remote server after installing .NET 4.5. When I use fiddler and sent a POST to a controller on my local machine it returns the correct response, yet when I change the domain to the webserver running IIS7 the same POST returns a cryptic

{"message":"an error has occurred"}

message. Anyone have any idea what could be going on?

The problem was a missing dependency that wasn't on the server but was on my local machine. In our case, it was a Devart.Data.Linq dll.

To get to that answer, I turned on IIS tracing for 500 errors. That gave a little bit of information, but the really helpful thing was in the web.config setting the <system.web><customErrors mode="Off"/></system.web> This pointed to a missing dynamically-loaded dependency. After adding this dependency and telling it to be copied locally, the server started working.

Get Started with ASP.NET Web API 2 (C#), Web API as the name suggests, is an API over the web which can be accessed using HTTP protocol. It is a concept and not a technology. We can build Web API​  A server-side web API is a programmatic interface consisting of one or more publicly exposed endpoints to a defined request–response message system, typically expressed in JSON or XML, which is exposed via the web—most commonly by means of an HTTP -based web server.

Basically:

Use IncludeErrorDetailPolicy instead if CustomErrors doesn't solve it for you (e.g. if you're ASP.NET stack is >2012):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

Note: Be careful returning detailed error info can reveal sensitive information to 'hackers'. See Simon's comment on this answer below.

TL;DR version

For me CustomErrors didn't really help. It was already set to Off, but I still only got a measly an error has occurred message. I guess the accepted answer is from 3 years ago which is a long time in the web word nowadays. I'm using Web API 2 and ASP.NET 5 (MVC 5) and Microsoft has moved away from an IIS-only strategy, while CustomErrors is old skool IIS ;).

Anyway, I had an issue on production that I didn't have locally. And then found I couldn't see the errors in Chrome's Network tab like I could on my dev machine. In the end I managed to solve it by installing Chrome on my production server and then browsing to the app there on the server itself (e.g. on 'localhost'). Then more detailed errors appeared with stack traces and all.

Only afterwards I found this article from Jimmy Bogard (Note: Jimmy is mr. AutoMapper!). The funny thing is that his article is also from 2012, but in it he already explains that CustomErrors doesn't help for this anymore, but that you CAN change the 'Error detail' by setting a different IncludeErrorDetailPolicy in the global WebApi configuration (e.g. WebApiConfig.cs):

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy 
= IncludeErrorDetailPolicy.Always;

Luckily he also explains how to set it up that webapi (2) DOES listen to your CustomErrors settings. That's a pretty sensible approach, and this allows you to go back to 2012 :P.

Note: The default value is 'LocalOnly', which explains why I was able to solve the problem the way I described, before finding this post. But I understand that not everybody can just remote to production and startup a browser (I know I mostly couldn't until I decided to go freelance AND DevOps).

What is Web API?, ASP.NET Web API is a framework for building HTTP services that can be accessed from any client including browsers and mobile devices. It is an ideal platform for  ASP.NET Web APIs REST APIs with.NET and C# ASP.NET makes it easy to build services that reach a broad range of clients, including browsers and mobile devices. With ASP.NET you use the same framework and patterns to build both web pages and services, side-by-side in the same project.

None of the other answers worked for me.

This did: (in Startup.cs)

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var config = new HttpConfiguration();

        WebApiConfig.Register(config);

        // Here: 
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
    }
}

(or you can put it in WebApiConfig.cs):

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        // Here: 
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
    }
}

ASP.NET Web API Tutorials, ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP. ASP.NET Web API is a framework for building HTTP services that can be consumed by a broad range of clients including browsers, mobiles, iphone and tablets. It is very similar to ASP.NET MVC since it contains the MVC features such as routing, controllers, action results, filter, model binders, IOC container or dependency injection.

I always come to this question when I hit an error in the test environment and remember, "I've done this before, but I can do it straight in the web.config without having to modify code and re-deploy to the test environment, but it takes 2 changes... what was it again?"

For future reference

<system.web>
   <customErrors mode="Off"></customErrors>
</system.web>

AND

<system.webServer>
  <httpErrors errorMode="Detailed" existingResponse="PassThrough"></httpErrors>
</system.webServer>

Web API, When writing code for the Web, there are a large number of Web APIs available. Below is a list of all the APIs and interfaces (object types) that  Web API is the enhanced form of the web application to provide services on different devices like laptop, mobile, and others. Today, all kind of businesses use the internet as a cost-effective way to expand their business in the international market.

I had a similar problem when posting to the WebAPI endpoint. By turning the CustomErrors=Off, i was able to see the actual error which is one of the dlls was missing.

Intro to WebAPI, Web API is a framework for building HTTP services that can be consumed by a broad range of clients including browsers, mobiles, iPhone and  A model is an object that represents the data in your application. ASP.NET Web API can automatically serialize your model to JSON, XML, or some other format, and then write the serialized data into the body of the HTTP response message. As long as a client can read the serialization format, it can deserialize the object.

What is ASP NET Web API, TradeStation’s WebAPI is a portal for integrating third-party trading applications to access real-time and historical market data, fast order-execution capabilities, and account and position information.

ASP.NET MVC - Web API, Call the web API with JavaScript. In this section, an HTML page is added that uses JavaScript to call the web API. jQuery initiates the request. JavaScript updates the page with the details from the web API's response. Configure the app to serve static files and enable default file mapping by updating Startup.cs with the following highlighted code:

Web APIs, In the above WebApiConfig.Register() method, config.MapHttpAttributeRoutes()enables attribute routing which we will learn later in this section. The config.Routesis a route table or route collection of type HttpRouteCollection. The "DefaultApi" route is added in the route table using MapHttpRoute()extension method.

Comments
  • What's the HTTP status code on the error response? If it's 500 it's very likely the web site/application config is invalid for the remote machine with IIS 7. Create a simple HTML file on the remote machine, browse it on the remote machine if possible to make sure it can be viewed and then try to hit it from your machine to see if it is successful or not.
  • It is a 500-error. Thanks for the suggestion, but the default index.html page that the WebApi provides works. Also should add that some of the API webservices work and others don't, whereas all of them work on my local machine.
  • You'll need to enable IIS request tracing to get more specifics when you see a 500 error. A 500 error usually occurs before the Web API routing kicks but I guess its possible to trigger it by something your code is doing. Look at the IIS trace logging and see if that offers any clues.
  • You might be able to get the server to give you more verbose error information in its response by initiating the request from a browser on the server machine itself (e.g. using a Remote Desktop session).
  • Looks like WebAPI will substitute {"message":"an error has occurred"} for the real response whenever the HTTP response code is 500 and custom errors are on. Thanks for the pointer.
  • Great suggestion about setting customErrors mode. I'm suprised changing that had an impact on the output of these kind of errors.
  • you can also set it to mode="RemoteOnly" and if you run the page on a webbrowser on the server you'll also see the errors without compromising security if the rest of the site is externally accessible
  • Any suggestions on how to get this kind of error detail when changing that setting isn't possible (e.g. errors are disabled at the machine level because the API part is hosted on a PCI-compatible server)? I tried setting up Elmah, but it's not logging anything unfortunately.
  • This is the best approach, gives enough info on such a generic method.
  • Now, this works. Thank you! I have some in-memory-integration-owin-kind of tests which fails on the build server, but not locally. With this setting in my startup-class, I may have a chance to figure out why.