简体   繁体   中英

Error 500 Web API

I've been trying to fix this for the last 4 hours.

I have a new Web API Project - which works 100% fine on development,

BUT on the live server I get a 500 Internal Server Error .

When I deploy a new version and send a request directly to http://URL/Action I get the error. BUT If I go to http://URL/ first then send the POST request to http://URL/Action , it works.

The same is the case when there is no request to the API for 12,13 hours

So for it to work first I have to open: http://URL/Action , then send the POST request.

So the Project uses Ninject and this is the Startup.cs

using System.Collections.Generic;
using System.Reflection;
using System.Web.Http;
using API.MyApi;
using Business.Bindings;
using Microsoft.Owin;
using Ninject;
using Ninject.Modules;
using Ninject.Web.Common.OwinHost;
using Ninject.Web.WebApi.OwinHost;
using Owin;

[assembly: OwinStartup(typeof(Startup))]
namespace API.MyApi
{

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

            app.UseNinjectMiddleware(CreateKernel);
            app.UseNinjectWebApi(config);

            GlobalConfiguration.Configuration.IncludeErrorDetailPolicy =  IncludeErrorDetailPolicy.Always;
        }

        private static StandardKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());

            var modules = new List<INinjectModule>
            {
                new BusinessBindings(),
                new DataBindings()
            };
            kernel.Load(modules);
            return kernel;
        }

    }
}

And the WebAPI Config

using System.Web.Http;

namespace API.MyApi
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
            config.Formatters.XmlFormatter.UseXmlSerializer = true;
            GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
        }
    }
}

I have tried adding this line of code to get a view of the entire error message:

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

and also adding this to the web.config file

<customErrors mode="Off"/>

But the error I get in PostMan is:

在此处输入图片说明

After I navigate to URL.com in the Browser:

在此处输入图片说明

Then If I send the POST request:

在此处输入图片说明

EDIT:

This is my exception handler attribute:

public class ExceptionHandlerAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        var exception = actionExecutedContext.Exception;

        using (var exceptionLogger = new CustomLogger("Exceptions"))
        {
            exceptionLogger.LogExceptionMessage(exception.Message, exception.InnerException, exception.StackTrace);
        }

        base.OnException(actionExecutedContext);
    }

}

and the Controller is decorated with the attribute:

[ExceptionHandler]
public class SmartOneCController : BaseApiController
{
    public SmartOneCController(CustomLogger logger)
    {
    }

}

So what this Attribute should do is Log the exception to a log file - Which is working tested on both the Development and the deployed version.

But is not logging the Exception from the 500 Internal Server Error

Controller Code, I don't see how the controller code will help here, as everything works after visiting the Base URL of the API: URL.com after that I can call this POST method and everything works.

[ExceptionHandler]
public class SmartOneCController : BaseApiController
{
    public SmartOneCController(CustomLogger logger, IAssetsProvider assetsProvider, ISatelliteTrackerProvider satelliteTrackerProvider) : base(logger, assetsProvider, satelliteTrackerProvider)
    {
    }

    public void Post(HttpRequestMessage request)
    {
        try
        {

            // Reading data as XML string to log to files - In case message structure is changed
            var xmlDoc = new XmlDocument();
            xmlDoc.Load(request.Content.ReadAsStreamAsync().Result);
            var str = xmlDoc.InnerXml;

            _logger.LogMessage(MessageType.Information, string.Format("RAW XML Message: {0}", str));

            // Convert to model

            var model = XMLHelper.FromXml<trackermessages>(str);
 ......

I would say its a routing/namespace issue. I would change the name of the controller and namespaces that you are using. Change API namespace and controller name. My guess is that somewhere it is causing a conflict which leads to the 500 error.

I was having the same issue recently. It drove me crazy, what caused the error in my case is that I had a controller named Reports that was causing a routing issue/conflict with SSRS. Just like your application, it works in development because the applications resources are never suspended where as in deployment, depending on settings whether it be IIS or Azure, application resources are suspended after a certain amount of time. The error occured on startup for some reason when the application would try to recover after being in a suspended state.

To obtain the exception you could attach the Visual Studio debugger to the IIS process using the remote debugger. If you don't have the required access to the remote machine, perhaps run IIS on your development workstation and try deploying the app locally, rather than running in development mode under VS. As for <customErrors> I've had more than occasion where changing this had no effect, so if you are able, try using a browser local to the deployment.

To rule out a routing, namespace or controller issue, you could also try adding a dummy method in the same controller with no external dependencies and see if calling that URL behaves the same way.

As for the way you are experiencing the issue; it sounds like the controller action you are executing via http://URL/Action possibly has some dependency that has not initialized yet, and by visiting http://URL/ first, you are giving the application time to initialize that dependency. The fact that this happens after a period of time would indicate that it's related to whether the application is already running in IIS, or the application pool has shut it down and the app needs to do a full start when you hit http://URL/

The Problem was with the Startup.cs class, Adding a default MapHttpRoute to the Configuration Method is what got it working

[assembly: OwinStartup(typeof(Startup))]
namespace API.MyApi
{

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

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

            app.UseNinjectMiddleware(CreateKernel);
            app.UseNinjectWebApi(webApiConfiguration);
        }

        private static StandardKernel CreateKernel()
        {
            var kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());

            var modules = new List<INinjectModule>
            {
                new BusinessBindings(),
                new DataBindings()
            };
            kernel.Load(modules);
            return kernel;
        }

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM