【问题标题】:Internal server error in an ASP.NET Web API in-memory testASP.NET Web API 内存测试中的内部服务器错误
【发布时间】:2012-05-29 10:23:29
【问题描述】:

in-memory test 中测试 ASP.NET Web API 控制器时,我收到“内部服务器错误”(状态代码 500)。

[TestFixture]
public class ValuesControllerTest
{
    private HttpResponseMessage response;

    [TestFixtureSetUp]
    public void Given()
    {
        var config = new HttpConfiguration
        {
            IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
        };

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { controller = typeof(ValuesController).Name.Replace("Controller", string.Empty), id = RouteParameter.Optional }
        );

        //This method will cause internal server error but NOT throw any exceptions
        //Remove this call and the test will be green
        ScanAssemblies();

        var server = new HttpServer(config);
        var client = new HttpClient(server);
        response = client.GetAsync("http://something/api/values/5").Result;
        //Here response has status code 500

    }

    private void ScanAssemblies()
    {
        PluginScanner.Scan(".\\", IsApiController);
    }

    private bool IsApiController(Type type)
    {
        return typeof (ApiController).IsAssignableFrom(type);
    }

    [Test]
    public void Can_GET_api_values_5()
    {
        Assert.IsTrue(response.IsSuccessStatusCode);
    }
}

public static class PluginScanner
{
    public static IEnumerable<Type> Scan(string directoryToScan, Func<Type, bool> filter)
    {
        var result = new List<Type>();
        var dir = new DirectoryInfo(directoryToScan);

        if (!dir.Exists) return result;

        foreach (var file in dir.EnumerateFiles("*.dll"))
        {
            result.AddRange(from type in Assembly.LoadFile(file.FullName).GetTypes()
                            where filter(type)
                            select type);
        }
        return result;
    }
}

我已将 Visual Studio 配置为在引发任何 .Net 异常时中断。代码不会因任何异常而停止,我也无法在响应中找到任何异常详细信息。

我应该怎么做才能查看导致“内部服务器错误”的原因?

【问题讨论】:

  • 堆栈跟踪是什么样的?把它放在这里。
  • 嗯,这就是问题所在。我没有得到堆栈跟踪。只有一个响应说“内部服务器错误”
  • // additional configuration 是什么意思?你有没有省略一些代码?
  • 更新了帖子,增加了评论。但那里没有例外。代码到达“var response = ...”
  • 对我来说,我发现我缺少 IncludeErrorDetailPolicy。一旦我将它包含在 hte HttpConfiguration 的创建中,我就能看到错误。希望这对其他人有帮助!

标签: asp.net asp.net-web-api


【解决方案1】:

您需要添加一条路线,使其看起来像这样:

        var config = new HttpConfiguration()
        {
            IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always
        };

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

        var server = new HttpServer(config);
        var client = new HttpClient(server);

        HttpResponseMessage response = client.GetAsync("http://somedomain/api/product").Result;

顺便说一句,在最新的位中,您会得到一个 404 Not Found,正如您所期望的那样。

亨里克

【讨论】:

  • 我已经准备好了。事实上,我有相当多的配置。路由、过滤器、IoC 容器等等。我的问题是管道中发生了一些事情,导致发回内部错误但没有相关信息。
  • @Martin Nilsson - Henrik 是 WebAPI 架构师。我会听他的。
【解决方案2】:

异常在 Response.Content 中

if (Response != null && Response.IsSuccessStatusCode == false)
{
    var result = Response.Content.ReadAsStringAsync().Result;
    Console.Out.WriteLine("Http operation unsuccessful");
    Console.Out.WriteLine(string.Format("Status: '{0}'", Response.StatusCode));
    Console.Out.WriteLine(string.Format("Reason: '{0}'", Response.ReasonPhrase));
    Console.Out.WriteLine(result);
}

【讨论】:

  • 正如另一个答案中所建议的,您可能需要设置错误详细信息策略 var config = new HttpConfiguration { IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always };
【解决方案3】:

听起来您可能已经找到了答案,但对我来说并不完全如此,所以我想为其他人添加这个问题。

首先,新的 MVC 4 格式化程序似乎存在问题。设置任何错误策略标志都不起作用(IncludeErrorDetailPolicy、CustomErrors 等),这些格式化程序会忽略它们,只是返回并清空“内部服务器错误”500。

我最终通过重载格式化程序并检查它们的响应是否有错误发现了这一点:

public class XmlMediaTypeFormatterWrapper : XmlMediaTypeFormatter
{
    public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, TransportContext transportContext)
    {
        var ret = base.WriteToStreamAsync(type, value, stream, contentHeaders, transportContext);
        if (null != ret.Exception)
            // This means there was an error and ret.Exception has all the error message data you would expect, but once you return below, all you get is a blank 500 error...

        return ret;
    } 
}

现在我正在使用 Xml 和 Json 格式化程序包装器,它们只是查找 ret.Exception 并捕获它,因此如果发生 500,我至少有数据。我真的找不到一种优雅的方法来让错误在 html 响应中实际显示,因为 Task.Exception 已经设置,这应该是传递异常所需的全部。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 2018-08-03
    • 1970-01-01
    • 2019-11-15
    • 2016-10-28
    • 2017-10-28
    • 2012-06-12
    相关资源
    最近更新 更多