C#点网核心动作过滤器-如何读取响应

时间:2018-11-17 12:10:41

标签: c# .net-core asp.net-core-2.0 asp.net-core-webapi

我有一个带有方法的动作过滤器:

public void OnActionExecuted(ActionExecutedContext context)
    {
        try
        {
            Stream originalBody = context.HttpContext.Response.Body;
            string responseBody = string.Empty;

            try
            {
                using (var memStream = new MemoryStream())
                {
                    context.HttpContext.Response.Body = memStream;

                    memStream.Position = 0;
                    responseBody = new StreamReader(memStream).ReadToEnd();

                    memStream.Position = 0;

                    memStream.CopyTo(originalBody);
                }

            }
            finally
            {
                context.HttpContext.Response.Body = originalBody;
            }

            _logger.LogDebug("OnActionExecuted, response=" + responseBody);

        }
        catch(Exception ex)
        {
            _logger.LogError(ex, "");
            //throw ex;
        }
        //throw new NotImplementedException();
    }

responseBody变量始终是一个空字符串。但是我对邮递员的回应不佳:

{"custId": "1235","Channel": "InternetBanking"}

我为什么不能在我的responseBody变量上得到它?

1 个答案:

答案 0 :(得分:0)

您的问题是您创建一个内存流,将其分配给Response.Body,但从不填充它:

using (var memStream = new MemoryStream())
{
    context.HttpContext.Response.Body = memStream;

    memStream.Position = 0;
    responseBody = new StreamReader(memStream).ReadToEnd();

    ...
}

在这段代码中,memStream只是一个空流,因此,当您阅读它时,它什么也不会读。

如果您尝试访问controller方法的结果,则可以通过context.Result属性来获取它。

还是您只是想在返回调用者之前记录响应正文?过滤器不是执行此操作的正确位置-过滤器更关心控制器方法中的参数和返回的对象。 MVC管道尚未填充Response.Body,因此您无法访问它-这是由MVC中间件完成的。

您需要创建自己的自定义中间件,以在填充Response对象时拦截该调用,并将其写入日志。有许多网站可以向您展示如何执行此操作。一个示例是here