以下代码是错误处理中间件的一部分,该中间件的目的是即使抛出错误也为客户端提供一致的格式。
当Accept
标头设置为application/xml
时,我试图将响应序列化为XML,否则返回JSON。本文帮助我入门: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);
}
else
块可以正常工作。如果我在声明XmlSerializer
的行上设置断点,则执行会暂停。如果我在下一行设置一个断点,则该断点将永远不会被击中。响应已经发送给客户端。
我的中间件配置如下:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStatusCodePagesWithReExecute("/error/{0}");
app.UseExceptionHandler("/error/500");
app.UseHsts();
app.UseMiddleware<ErrorWrappingMiddleware>();
app.UseMvc();
}
为什么在context.Response.WriteAsync(stringwriter.ToString());
块中调用if
之前将响应返回给客户端?
答案 0 :(得分:1)
我发现了问题,这是一个愚蠢的错误。
为了测试500个错误,我有意向模型添加了一个属性,该模型在数据库中没有相应的列。这会在无效的列名上抛出SqlException
。但是,我错过了第二个例外,确切地告诉了我问题出在什么地方:
ApiResponse cannot be serialized because it does not have a parameterless constructor.
这发生在对serializer.Serialize(stringwriter, response)
的呼叫中。我引用的示例创建一个ApiResponse
类(我尝试序列化的response
)。但是,在我正在学习的示例中,该类没有无参数的构造函数,并且直到我找到this答案之前,我才意识到这是没有必要的。第二个异常停止了执行,但是由于我忘记打开开发模式并且试图抛出一个异常,因此我没有注意到第二个异常。