2012-05-22 27 views
5

我在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拋出異常打破。代碼不會在任何異常情況下停止,也不能在響應中找到任何異常詳細信息。

我應該怎麼做,看看是什麼導致了「內部服務器錯誤」?

+0

什麼是堆棧跟蹤什麼樣的?把這個放在這裏。 – Aliostad

+0

那麼,這就是問題所在。我沒有得到堆棧跟蹤。只有一個迴應說「內部服務器錯誤」 –

+0

「//附加配置」是什麼意思?你有沒有遺漏一些代碼? – Aliostad

回答

9

唯一的例外是在Response.Content

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

作爲另一個答案建議你可能需要設置錯誤詳細政策 無功配置=新HttpConfiguration {IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always}; –

4

您需要添加一個路由,這樣它看起來是這樣的:

 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未找到你所期望的。

亨裏克

+0

我已經準備好了。實際上,我有很多配置。路由,過濾器,IoC容器等。我的問題是管道中發生了一些事情,導致發送內部錯誤,但沒有關於它的信息。 –

+0

@Martin Nilsson - Henrik是WebAPI架構師。我會聽他的。 – RickAndMSFT

0

這聽起來像你可能已經發現你的答案,但是這並不完全是對我,所以我要添加本作其他與我的問題。

要開始了,這似乎是與新的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已經設置,這應該是所有需要傳遞下去例外。