C# 如何在EmbedIO Web API中设置异常处理程序
我正在使用WebAPI模块 我希望有一个异常处理程序,它将捕获所有未处理的异常,并根据异常类型返回合适的HTTP错误代码。然而,这是否能够实现还不清楚 该类公开了一个名为OnUnhandledException的属性,该属性可以设置为ExceptionHandlerCallback,但在调用回调时,响应的状态代码已设置为HttpStatusCode.InternalServerError,如中所述 这不方便,因为我想自己设置响应代码 WebModuleBase公开一个名为OnHttpException的不同属性,该属性可以设置为。这可以设置为 DataResponse(ResponseSerializer.Json)部分解决了这个问题 现在主要的问题是应用程序异常必须在控制器中转换为HttpException 我想从域代码中抛出自定义异常,将它们放入异常处理程序中,然后根据初始异常返回一个HTTPException 基本上类似于ASP.NET Web API中的内容 以下是设置web服务器的代码:C# 如何在EmbedIO Web API中设置异常处理程序,c#,embedio,C#,Embedio,我正在使用WebAPI模块 我希望有一个异常处理程序,它将捕获所有未处理的异常,并根据异常类型返回合适的HTTP错误代码。然而,这是否能够实现还不清楚 该类公开了一个名为OnUnhandledException的属性,该属性可以设置为ExceptionHandlerCallback,但在调用回调时,响应的状态代码已设置为HttpStatusCode.InternalServerError,如中所述 这不方便,因为我想自己设置响应代码 WebModuleBase公开一个名为OnHttpExcept
var webApiModule = new WebApiModule("/api", ResponseSerializer.Json)
.WithController<MyController>();
webApiModule.OnUnhandledException = ExceptionHandler.DataResponseForException();
webApiModule.OnHttpException = ExceptionHandler.DataResponseForHttpException();
WebServerEmbedded = new EmbedIO.WebServer(
opt => opt
.WithUrlPrefix(url)
.WithMode(HttpListenerMode.EmbedIO))
.WithModule(null, webApiModule);
谢谢。异常以及HTTP异常都由EmbedIO在模块和服务器级别处理(每个嵌套模块组引入了一个更高的级别,但这超出了重点) HTTP异常的
catch
子句总是位于“通用”的catch
子句之前,原因很明显,HTTP异常本身就是异常,需要进行分类。因此,如果异常处理程序抛出HTTP异常,则后者必须在外部级别处理
换句话说,您可以编写一个抛出HTTP异常的模块级异常处理程序,然后使用服务器级HTTP异常处理程序生成适当的响应
var webApiModule = new WebApiModule("/api", ResponseSerializer.Json)
.WithController<MyController>()
.HandleUnhandledException(ExceptionHandler.DataResponseForException));
WebServerEmbedded = new EmbedIO.WebServer(
opt => opt
.WithUrlPrefix(url)
.WithMode(HttpListenerMode.EmbedIO))
.WithModule(webApiModule)
.HandleHttpException(ExceptionHandler.DataResponseForHttpException);
编辑:如果您需要自定义异常,有一种更简单的方法:只需实现您的异常 您可以看到HTTP异常处理代码如何使用
IHTTPEException
方法
可能是最模糊的方法,PrepareResponse
的一个例子
编辑:我在
DataResponseForHttpException
中添加了设置状态代码的功能。是否要使用自定义异常,比如说InvalidOperationException,然后抛出它并将其转换为HTTPException?是的,完全正确。例如,假设我的存储库层正在抛出一个名为EntityNotFoundException的自定义异常。我希望能够在web项目中的异常处理程序中捕获此问题,并基于此抛出HttpNotFound。您能否将此问题发布到我找到了一个解决方法,我将很快发布此修复程序。您可以查看PR:谢谢您的回答。我尝试了你建议的第一种方法,但代码总是500。请参见问题描述的开头:“WebModuleBase类公开了一个名为OnUnhandledException的属性,该属性可以设置为ExceptionHandlerCallback,但在调用回调时,响应的状态代码已经设置为HttpStatusCode.InternalServerError,如代码注释中所述。”至于第二个建议,我不能让与HTTP无关的异常类实现IHTTPEException。还是我误解了你的建议?@Paul响应的状态代码已经设置好了,但是可以由exceptiopn处理程序重新设置,因为在调用客户端时还没有将头发送到客户端。当然,您可以拥有自己的异常类,并且它们没有义务实现IHTTPEException
。我只是建议,如果您关心的异常都是您自己的(即您的应用程序的一部分),让它们实现IHTTPEException
是一种快速的方法,可以为每个异常提供自己的响应代码,以及它们自己的消息,甚至自定义头(如果需要)。此外,如果您的响应代码取决于异常的类型,那么让每个响应代码直接由异常设置—而不是在异常处理程序中的开关
语句(或一系列catch
子句)中设置—将使代码更干净。
var webApiModule = new WebApiModule("/api", ResponseSerializer.Json)
.WithController<MyController>()
.HandleUnhandledException(ExceptionHandler.DataResponseForException));
WebServerEmbedded = new EmbedIO.WebServer(
opt => opt
.WithUrlPrefix(url)
.WithMode(HttpListenerMode.EmbedIO))
.WithModule(webApiModule)
.HandleHttpException(ExceptionHandler.DataResponseForHttpException);
internal static class ExceptionHandler
{
public static Task DataResponseForException(IHttpContext context, Exception exception)
{
// Replace ANY_VALID_STATUS CODE with, well, any valid status code.
// Of course you can use different status codes according to, for example,
// the type of exception.
throw new HttpException(ANY_VALID_STATUS_CODE, exception.Message);
}
public static Task DataResponseForHttpException(IHttpContext context, IHttpException httpException)
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
return ResponseSerializer.Json(context, httpException.Message);
}
}