2017-08-11 84 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