2017-08-11 91 views
1

編輯:Issue on GitHub here在南希捕獲序列化錯誤


與南希玩周圍的第一次寫了這個簡單的端點基於Accept頭測試內容協商:

public HomeModule() 
{ 
    Get["/"] = _ => new { Foo = "Bar" }; 
} 

使用Postman,我設置Accept: application/json,並如預期的結果,而Accept: text/xml產生文本:

時發生錯誤,生成XML文檔

經過一些試驗和錯誤,我發現這是由匿名類型引起的,這是關於XmlSerializer的單獨問題。但是,我無法弄清楚如何在任何地方捕獲這個序列化錯誤。就像它在南希或ASP.NET的某個地方「吞噬」。上述消息作爲文本返回給請求者,狀態碼爲200 OK

儘管有安裝Visual Studio來上所有例外打破以及掛接到pipelines.OnErrorApplication_OnError,我沒有得到任何跡象表明發生了錯誤。我不確定這是否是一般的序列化程序,ASP.NET或Nancy的問題(​​或者我錯過了某些明顯的東西)。

// in bootstrapper's ApplicationStartup method: 

pipelines.OnError += (ctx, ex) => { 
    System.Diagnostics.Trace.WriteLine(ex?.ToString()); // doesn't fire 
    return null; 
}; 

// in Global.asax: 

protected void Application_Error(object sender, EventArgs e) 
{ 
    var err = Server.GetLastError(); 
    System.Diagnostics.Trace.WriteLine(err?.Message); 
} 

爲什麼這個錯誤不被拋出/可捕獲?

回答

2

Nancy使用.Net XmlSerializer來進行XML序列化。和.NET XmlSerliazer不能序列匿名類型:

https://github.com/NancyFx/Nancy/wiki/Extending-Serialization-with-Converters

南希使用.NET Framework本身內置的XmlSerializer 基礎設施來滿足客戶發送和使用XML作爲 傳輸格式接收數據。

Can I serialize Anonymous Types as xml?

對不起,你不能。 XML Serializer幾乎只是序列化公共讀寫類型。

你要麼需要返回POCO(普通老式-CSHARP-對象)這樣

public class HomeModule:NancyModule 
{ 
    public class FooModel 
    { 
     public string Foo { get; set; } 
    } 

    public HomeApi() 
    { 
     Get("/", p => 
     { 
      var r = new F { Foo = "Bar" }; 
      return r; 
     }); 
    } 
} 

或實現另一個XmlSerialiser

https://github.com/NancyFx/Nancy/wiki/Extending-Serialization-with-Converters

的設計XmlSerializer是可擴展的,它的可擴展性不同於 JSON序列化所使用的JavaScriptConverter和JavaScriptPrimitiveConverter類型。 XmlSerializer不知道JSON 轉換器,JavaScriptSerializer忽略XML特定的屬性。 因此,對XML序列化和JSON序列化的擴展可以共存於同一個項目中,而不會相互干擾。

基於南希的內部。來自串行器的錯誤消息被寫入輸出端,即There was an error generating the XML document.。但是例外的細節不會寫在任何地方。

https://github.com/NancyFx/Nancy/blob/master/src/Nancy/Responses/DefaultXmlSerializer.cs

catch (Exception exception) 
{ 
    if (this.traceConfiguration.DisplayErrorTraces) 
    { 
     var bytes = Encoding.UTF8.GetBytes(exception.Message); 
     outputStream.Write(bytes, 0, exception.Message.Length); 
    } 
} 

爲了看到錯誤,你需要在Visual Studio中關閉只是,我的碼要解決它。您可以通過以下步驟做到這一點:

Debug->Options然後取消Just-My-Code

enter image description here

然後去Debug->Windows-Exception Settings (Ctrl+Alt+E)。檢查Common Language Runtime Exceptions

enter image description here

+0

謝謝回答,傑夫。我意識到XmlSerializer是關於序列化的罪魁禍首,並且修復很容易。我的問題涉及這樣的事實,即錯誤隱藏在200 OK響應後面,我發現它很奇怪。我希望能夠在某處捕獲/記錄錯誤。你能對此有所瞭解嗎? – bernhof

+0

謝謝,所以*有*錯誤,但它被DefaultXmlSerializer隱藏起來。我現在想知道這是爲什麼。再說一次,當發生這樣的錯誤時,我不會期望** 200 OK **響應,但是我會在GitHub上提出一個問題:乾杯! – bernhof