ActionFilter Response.StatusCode总是200

时间:2018-05-22 08:57:07

标签: c# asp.net-core-mvc

我正在尝试设置一个动作过滤器,只有在StatusCode的{​​{1}}为302时才会执行某些操作。

我希望能够在HttpContext.Response方法中执行此操作,但OnActionExecuting始终为StatusCode

200代码:

ActionFilter

我的public class CustomFilter : IActionFilter { public void OnActionExecuting(ActionExecutingContext context) { // do some setup } public void OnActionExecuted(ActionExecutedContext context) { if (context.HttpContext.Response.StatusCode == StatusCodes.Status302Found) { // never get here } } } 方法:

Action

public IActionResult Redirect() { return RedirectToAction("Index", "Home"); } 注册ActionFilter

startup

我已经在浏览器中检查过它正确返回302并进行重定向。我也尝试使用public void ConfigureServices( IServiceCollection services) { services.AddMvc( options => { options.Filters.Add(new CustomFilter()); }); } 界面,但遇到了同样的问题。

如何将IAsyncActionFilter应用于()重定向的响应?

为什么这不起作用?

编辑:哎呀我把它们绕错了。实际上我仍然遇到这个问题......

4 个答案:

答案 0 :(得分:5)

在查看实际生成响应之前,您正在查看响应的状态代码。 OnActionExecuting called before操作已执行,因此尚未设置状态代码。 Default value状态代码为200,这就是您所看到的内容。

为了能够看到已为响应分配的其他操作的实际状态代码,您需要查看OnActionExecutedruns after操作。

<强>更新

另一个问题可能是核心框架中的操作过滤器在执行操作之前和之后运行。因此,尚未处理响应,并且未在http响应对象中设置状态代码。

适用于您的用例seems to be IResultFilter.OnResultExecuted

的方法

答案 1 :(得分:2)

您可以尝试将ActionExecutedContext.Result对象转换为ObjectResult,并从其中检索StatusCode

public void OnActionExecuted(ActionExecutedContext context) { var statusCode = (context.Result as ObjectResult)?.StatusCode }

答案 2 :(得分:1)

根据先前的答案,为了避免as或cast,您可以只使用反射

PropertyInfo pi = context.Result.GetType().GetProperty("StatusCode");
int httpCode = -1;
if (pi != null && pi.CanRead && pi.PropertyType == typeof(int)) httpCode = (int)pi.GetValue(context.Result);

因此,如果存在 StatusCode 属性,则无论底层结果类是什么类型,都将读取该属性。

答案 3 :(得分:0)

int? statusCode = null;
ObjectResult result = context.Result as ObjectResult;
statusCode = result?.StatusCode;

if (statusCode == null)
{
    StatusCodeResult statusResult = context.Result as StatusCodeResult;
    statusCode = statusResult?.StatusCode;
}