从 .Net Core 2.0 中的 IActionFilter 获取 HttpStatus 代码
Get HttpStatus code from IActionFilter in .Net Core 2.0
我在 ASP.NET 核心 2.0 中有过滤器属性,请参阅下面的代码片段。这里的问题是我总是得到状态码是 200。
即使实际状态代码是 500,我也得到 200。我如何获得实际状态代码?
public void OnActionExecuted(ActionExecutedContext context)
{
try
{
var controller = context.Controller as APIServiceBase;
var statusCode = controller.Response.StatusCode;
..
..
}
catch { }
}
很有趣的问题。动作过滤器在动作本身之后执行。问题是动作返回的 IActionResult
在这个阶段还没有执行。您可以通过返回 IActionResult
的自定义实现并检查其 ExecuteResultAsync
方法是否在动作过滤器 OnActionExecuted()
之后执行来检查它。
由于响应是由 IActionResult
填充的(包括状态代码),您不应期望 Response.StatusCode
已经在操作过滤器中设置。
要解决这个问题,您应该稍后在 ASP.Net 核心管道中执行您的逻辑,动作过滤器不适合它。您可以在请求管道中添加自定义中间件(Startup.Configure()
方法):
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (context, next) =>
{
await next.Invoke();
var statusCode = context.Response.StatusCode;
// ...
});
app.UseMvc();
}
确保在调用 app.UseMvc()
之前添加它。如果需要,您可以包装委托逻辑以分隔 class。
正如 CodeFuller 所提出的,您的操作可能尚未执行。
但是,如果您想保留一个过滤器模式以仅将其应用于特定方法,您可以使用响应的 OnCompleted
方法:
// Called on incoming request
public void OnActionExecuting(ActionExecutedContext context)
{
context.HttpContext.Response.OnCompleted(async () => {
// Executed once the response is sent
var status = context.HttpContext.Response.StatusCode;
// Work here
// Be careful on Transient or Scoped injections, they may already be disposed
// If you need a DbContext, instanciate it by injecting
// DbContextOptions<MyDbContext> earlier in the code
});
}
此方法适用于大多数类型的过滤器,因此您可以根据需要的过滤器输入使用 any。
我在 ASP.NET 核心 2.0 中有过滤器属性,请参阅下面的代码片段。这里的问题是我总是得到状态码是 200。
即使实际状态代码是 500,我也得到 200。我如何获得实际状态代码?
public void OnActionExecuted(ActionExecutedContext context)
{
try
{
var controller = context.Controller as APIServiceBase;
var statusCode = controller.Response.StatusCode;
..
..
}
catch { }
}
很有趣的问题。动作过滤器在动作本身之后执行。问题是动作返回的 IActionResult
在这个阶段还没有执行。您可以通过返回 IActionResult
的自定义实现并检查其 ExecuteResultAsync
方法是否在动作过滤器 OnActionExecuted()
之后执行来检查它。
由于响应是由 IActionResult
填充的(包括状态代码),您不应期望 Response.StatusCode
已经在操作过滤器中设置。
要解决这个问题,您应该稍后在 ASP.Net 核心管道中执行您的逻辑,动作过滤器不适合它。您可以在请求管道中添加自定义中间件(Startup.Configure()
方法):
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (context, next) =>
{
await next.Invoke();
var statusCode = context.Response.StatusCode;
// ...
});
app.UseMvc();
}
确保在调用 app.UseMvc()
之前添加它。如果需要,您可以包装委托逻辑以分隔 class。
正如 CodeFuller 所提出的,您的操作可能尚未执行。
但是,如果您想保留一个过滤器模式以仅将其应用于特定方法,您可以使用响应的 OnCompleted
方法:
// Called on incoming request
public void OnActionExecuting(ActionExecutedContext context)
{
context.HttpContext.Response.OnCompleted(async () => {
// Executed once the response is sent
var status = context.HttpContext.Response.StatusCode;
// Work here
// Be careful on Transient or Scoped injections, they may already be disposed
// If you need a DbContext, instanciate it by injecting
// DbContextOptions<MyDbContext> earlier in the code
});
}
此方法适用于大多数类型的过滤器,因此您可以根据需要的过滤器输入使用 any。