如何更好地排除MVC Web API中的500错误

问题描述:

我有一个我正在开发的MVC Web API项目。我用一个动作创建了一个控制器。我能够使用Postman正确地执行操作,但是当外部系统尝试连接到我的控制器时,它会得到500错误。外部服务的所有者不能再给我任何细节,他们只能重试请求。如何更好地排除MVC Web API中的500错误

这里是他们的要求在IIS日志条目的一个记录

#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken 
2017-02-15 20:38:58 192.168.2.34 POST /Route/to/actionName 8002 - 192.168.2.37 Apache-HttpClient/4.5.2+(Java/1.8.0_102) - 500 0 0 146 

首先我想可能是动作被打,所以我加了一个异常处理程序,并添加记录。

[Route("actionName")] 
[HttpPost] 
public IHttpActionResult actionName(MessageModel message) 
{ 
try 
{ 
    // code to handle the action 
} 
catch (Exception e) 
{ 
    // Code to log exception in the log file 
} 
} 

尝试了上述什么都没看见在日志中,我已经运行试验失败的请求,以确保上述异常处理程序日志和它的作用。

因此,我决定做的下一件事是处理Global.asax中的应用程序级错误并在那里记录异常。

protected void Application_Error(object sender, EventArgs e) 
{ 
    if (Request.HttpMethod == "POST") 
    { 
     var request = SomeMethodToReadRequestContentsInString(); 

     var service = new SomeExceptionLoggingService(); 

     var exception = Server.GetLastError(); 
     if (exception == null) 
     { 
      exception = new ApplicationException("Unknown error occurred"); 
     } 
     service.LogException(exception, Request.UserHostAddress, Request.UserAgent, request); 
    } 
} 

令人惊讶的是,在日志文件中没有任何东西。

那么我决定记录所有发布请求,看看我是否在日志中注册任何东西。

protected void Application_EndRequest(object sender, EventArgs e) 
{ 
    if (Request.HttpMethod == "POST") 
    { 
     var request = Helper.ReadStreamUnknownEncoding(Request.InputStream); 

     var service = new InterfaceTestingService(); 

     var exception = Server.GetLastError(); 
     if (exception == null) 
     { 
      exception = new ApplicationException("No Error in this request"); 
     } 
     service.LogException(exception, Request.UserHostAddress, Request.UserAgent, request); 
    } 
} 

再次,没有!

如何捕获此错误?我的目标是看到Content-Type和内容。

我试图在IIS日志设置中添加一个Custom Field以包含“Content-Type”,但日志文件仍然没有。

enter image description here

+0

打开你的服务器上的调试,那么你会得到实际的错误,而不是通用的错误页面...只是确保你把它关闭,因为它是一个巨大的安全风险。 – BillRuhl

+0

@BillRuhl在返回的HTTP状态代码之外,调用者不能提供更多信息(是的,这很愚蠢)。更令人迷惑的是为什么我无法在全球的asax处理程序中捕捉到它。 – fahadash

+0

嗯,我认为他们非常*有*给你更多的信息。明白地说,他们只能得到你的服务器在发生的实际错误方面的回应,但他们有更多的信息可以帮助你排除故障,即:URI,请求方法和请求主体。鉴于你只记录POST,而你没有得到任何日志,我的猜测是他们甚至没有做POST。他们也可能会调用错误的端点或以错误的格式发送错误类型的数据或数据。你需要这些信息。 –

我增加了一个处理程序Application_BeginRequest记录的一切,我在Application_EndRequest一样。事实证明,内容长度为零,并且没有内容。我也重新启动了IIS Web服务器,让它也记录自定义字段。

奇怪的是,如果我通过Postman发送空白内容,我会执行操作代码,但由于某种原因,当它们执行时,它不会。