Edit: Issue on GitHub here.
Playing around with Nancy for the first time and wrote this simple endpoint to test content negotiation based on Accept
header:
public HomeModule()
{
Get["/"] = _ => new { Foo = "Bar" };
}
Using Postman, I set Accept: application/json
and the result is as expected, while Accept: text/xml
yields the text:
There was an error generating XML document
After some trial and error I found that this is caused by the anonymous type, and this is a separate issue concerning the XmlSerializer. However, I can't figure out how to capture this serialization error anywhere. It's like it's "swallowed" somewhere in Nancy or ASP.NET. The above message is returned as text to the requester with status code 200 OK.
Despite having setup Visual Studio to break on all exceptions as well as hooking up to pipelines.OnError
and Application_OnError
, I get no indication that an error occurred. I'm uncertain whether this is a problem with the serializer in general, ASP.NET or Nancy (or if I'm missing something obvious).
// 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);
}
Why is this error not thrown/capturable?
Nancy uses .Net XmlSerializer
to XML serializations. And .Net XmlSerliazer
cannot serialize anonymous types:
https://github.com/NancyFx/Nancy/wiki/Extending-Serialization-with-Converters
Nancy uses the .NET Framework's own built-in XmlSerializer infrastructure to handle clients sending and receiving data using XML as the transport format.
Can I serialize Anonymous Types as xml?
Sorry, you cannot. The XML Serializer pretty much just serializes public read-write types.
You will need to either return a POCO (Plain-Old-CSharp-Object) like this
public class HomeModule:NancyModule
{
public class FooModel
{
public string Foo { get; set; }
}
public HomeApi()
{
Get("/", p =>
{
var r = new F { Foo = "Bar" };
return r;
});
}
}
or implement another XmlSerialiser
https://github.com/NancyFx/Nancy/wiki/Extending-Serialization-with-Converters
The design of XmlSerializer is quite extensible, and the way in which it is extensible is different from the JavaScriptConverter and JavaScriptPrimitiveConverter types that JSON serialization employs. XmlSerializer is unaware of JSON converters, and JavaScriptSerializer ignores XML-specific attributes. Thus, extensions to XML serialization and to JSON serialization can coexist in the same project without interfering with one another.
Based on Nancy's internals. The error message from Serialiser is written to the output i.e There was an error generating the XML document.
. But details of the exception are not written anywhere.
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);
}
}
In order to see the error, you need to workaround it by turning off Just-My-Code in Visual Studio. You can do this by the following steps:
Debug->Options
and then Uncheck Just-My-Code
And then go to Debug->Windows-Exception Settings (Ctrl+Alt+E)
. Check Common Language Runtime Exceptions