bernhof bernhof - 1 year ago 69
ASP.NET (C#) Question

Capturing serialization error in Nancy

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?

Answer Source

Nancy uses .Net XmlSerializer to XML serializations. And .Net XmlSerliazer cannot serialize anonymouse 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

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download