NET Web API: 非描述性500内部服务器错误

正如标题所说,我有500个内部服务器错误,从 GET 请求到一个 IQueryable 操作。错误体是空的。该错误发生在操作返回结果之后。

我使用 ASP.NET Web API RC。

如何获得该错误的堆栈跟踪?

106585 次浏览

你可以试着加上:

GlobalConfiguration.Configuration.IncludeErrorDetailPolicy =
IncludeErrorDetailPolicy.Always;

这个解决方案适用于许多常见错误。

但是,如果您没有得到令人满意的信息,您应该考虑编写一个 l 异常筛选器并在全球注册它。

这篇文章 应该可以让你开始,你需要的核心是写和注册一些东西,比如:

public class NotImplExceptionFilter : ExceptionFilterAttribute {
public override void OnException(HttpActionExecutedContext context) {
if (context.Exception is NotImplementedException) {
context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
}
}
}

后 RC,这个问题是固定的,你会得到错误的详细信息也除了500内部服务器错误。(此问题仅针对 Web 主机场景修复)。

您可以执行以下操作来获取在格式化程序的 WriteToStream 方法期间可能发生的实际异常的详细信息。

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();

当我没有按照正确的顺序指定查询参数时,我在 RC 中遇到了这个问题。例如,如果指定 $skip=0,它将得到500,但是如果指定 $orderby=xxx&skip=0,则没有错误。

Fredrik Normén 写了一篇关于这个话题的很棒的博客文章,名为 Web API 异常处理。他的解决方案使用自定义异常类和异常筛选器属性,该属性可应用于所有 ApiController操作方法。

我也遇到了同样的问题。我发现 Kiran Challa 的回答对于将实际异常抛出到操作之外很有帮助。

为了解决我的问题,将上下文的 ProxyCreationEnable 属性设置为 false让我更进一步。

在我的场景中,我的下一个异常是由于我的模型中的循环引用。清理干净之后,幽灵500响应消失了。祝你好运,如果你还没有解决这个问题!

我通常使用 Global.asax 来捕捉所有错误

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;
}

这可能与循环引用有关。

Http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#handling_circular_object_references

尝试将下面的代码添加到 Global.asax 文件中的 Application _ Start 方法:

 var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;

在我的例子中,一个极其简单的路由缺陷导致了这个问题: 在我的 Api 控制器中有另一个具有相同签名(不是名称)的 HttpPost。默认的路由没有解决名称差异,ServiceError 500是它在到达任何一个 Api 函数之前给出的响应。解决方案: 更改默认路由或签名,然后重试。

下面是我的 RouteConfig.cs,它非常适合于标准的 WebApi2使用:

    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 }
);
}
}

我也有同样的问题,但问题的根源略有不同: 我错误地设置了 CORS策略,这样就得到了 500 Internal server error,但是由于 CORS不起作用,因此在响应中没有显示 Access-Control-Allow-Origin报头,浏览器无法读取实际的响应

我用 ChromeDevTools 选项 Copy as cURL解决了这个问题,它允许我查看响应并了解错误的来源

此场景是由于以下原因引起的

  1. 问题是由于格式错误的 Web.config (多个 configSections)造成的

  2. 我没有在 垃圾箱文件夹中创建 Roslyn文件夹,而是在根目录中创建了它

诊断这种情况的最佳方法是,在应用程序位置放置一个简单的 HTML 页面并尝试浏览它。500错误描述将显示在这个 html 页面上。

还有别忘了加上

<customErrors mode="Off"></customErrors>

到 Web.config