1

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?

bernhof
  • 6,219
  • 2
  • 45
  • 71

1 Answers1

2

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

enter image description here

And then go to Debug->Windows-Exception Settings (Ctrl+Alt+E). Check Common Language Runtime Exceptions

enter image description here

Joe
  • 7,113
  • 1
  • 29
  • 34
Jeff Pang
  • 161
  • 1
  • 6
  • Thanks for answering, Jeff. I realize that the XmlSerializer is the culprit with regards to the serialization, and the fix is easy. My question relates to the fact that the error is hidden behind a 200 OK response, which I find odd. I would have expected to be able to catch/log the error somewhere. Can you shed some light on this? – bernhof Aug 17 '17 at 09:52
  • Thanks, so there *is* an error but it's hidden away by the DefaultXmlSerializer. I'm wondering now why this is. Again, I wouldn't expect a **200 OK** response when an error like this occurs, but I'll raise an issue re: this on GitHub. Cheers! – bernhof Aug 17 '17 at 10:30