Reputation: 2099
The following code is part of an error handling middleware, whose goal is to provide consistent formatting for the client even if an error is thrown.
I am trying to serialize a response as XML when the Accept
header is set to application/xml
, otherwise return JSON. This article helped get me started: https://www.devtrends.co.uk/blog/handling-errors-in-asp.net-core-web-api
if (context.Request.Headers["Accept"] == "application/xml")
{
context.Response.ContentType = "application/xml";
using (var stringwriter = new StringWriter())
{
var serializer = new XmlSerializer(response.GetType());
serializer.Serialize(stringwriter, response);
await context.Response.WriteAsync(stringwriter.ToString());
}
}
else {
context.Response.ContentType = "application/json";
var json = JsonConvert.SerializeObject(response);
await context.Response.WriteAsync(json);
}
The else
block works as expected. If I set a breakpoint on the line where the XmlSerializer
is declared, execution halts. If I set a breakpoint on the following line, the breakpoint is never hit; a response has already been sent to the client.
My middleware is configured like this:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStatusCodePagesWithReExecute("/error/{0}");
app.UseExceptionHandler("/error/500");
app.UseHsts();
app.UseMiddleware<ErrorWrappingMiddleware>();
app.UseMvc();
}
Why is a response returned to the client before context.Response.WriteAsync(stringwriter.ToString());
is called in the if
block?
Upvotes: 0
Views: 645
Reputation: 2099
I figured out the problem, it was a silly mistake.
To test 500 errors, I was intentionally adding a property to a model that didn't have a corresponding column in the database. This throws a SqlException
on an invalid column name. There was however a second exception I missed that told me exactly what the problem was:
ApiResponse cannot be serialized because it does not have a parameterless constructor.
This occurred in the call to serializer.Serialize(stringwriter, response)
. The example I referenced creates an ApiResponse
class (the response
I attempted to serialize). However this class does not have a parameterless constructor in the example I was learning from, and I wasn't aware this was necessary until I found this answer. This second exception halted execution, but since I forgot to turn on development mode and I was trying to throw an exception, I didn't notice the second one.
Upvotes: 1