WebApi在过滤器中获取帖子的原始正文

本文关键字:原始 正文 获取 过滤器 WebApi | 更新日期: 2023-09-27 18:10:48

我正在创建一个日志,我需要检索请求体保存在数据库中。我用HttpActionContext创建了一个过滤器。我尝试恢复通过filterContext.Request.Content.ReadAsStringAsync().Result;但是它总是返回一个空字符串。

LogFilter.cs

public override void OnActionExecuting(HttpActionContext filterContext)
    {
        try
        {
            Task<string> content = filterContext.Request.Content.ReadAsStringAsync();
            string body = content.Result;
            logModel.RequestLog rl = new logModel.RequestLog();
            rl.IP = ((HttpContextWrapper)filterContext.Request.Properties["MS_HttpContext"]).Request.UserHostAddress;
            rl.Type = filterContext.ControllerContext.RouteData.Values["controller"].ToString().ToUpper();
            rl.URL = filterContext.Request.RequestUri.OriginalString;
            rl.Operation = filterContext.Request.Method.Method;
            rl.RequestDate = DateTime.Now;

            filterContext.ControllerContext.RouteData.Values.Add("reqID", new deviceLog.RequestLog().Add(rl).ID.ToString());
        }
        catch { }
        //return new deviceLog.RequestLog().Add(rl);
        base.OnActionExecuting(filterContext);
    }

WebApi在过滤器中获取帖子的原始正文

请求流可能已经到达终点。尝试将流位置重置到起始位置:

public class MyAttribute:ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionContext actionContext)
    {
        string rawRequest;
        using (var stream = new StreamReader(actionContext.Request.Content.ReadAsStreamAsync().Result))
        {
            stream.BaseStream.Position = 0;
            rawRequest = stream.ReadToEnd();
        }
    }
}

快7年了…我的任务是为一个遗留项目创建一个过滤器——大约有8年的历史——没有任何模式或架构。

我尝试使用stream/string async从流中读取,但它不允许您读取多次,并且在动作过滤器- Seek为假,位置为只读之前已经读取了。

我试过反思,但收效甚微,我又不喜欢。

我试着获取"MS_HttpContext"但是字典里没有。

经过8个小时的研究,我妥协了从请求中获取所有操作参数,并将它们转换为Json。

对于4.7框架API:

private string requestBody = "";
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        requestBody = JsonConvert.SerializeObject(actionContext.ActionArguments);
        base.OnActionExecuting(actionContext);
    }

对于。net 5.0:

我在onresultperformed方法上使用这个。流已经被读取,所以你需要在0处重新定位请求体。

private static async Task<string> FormatRequestBody(HttpRequest request)
        {
            // we set the stream position to 0 to reset the pointer. If this is not done, the read stream will be incorrect and the Body will be empty
            request.Body.Position = 0;
            // We now need to read the request stream.  First, we create a new byte[] with the same length as the request stream...
            var buffer = new byte[Convert.ToInt32(request.ContentLength)];
            //...Then we copy the entire request stream into the new buffer.
            await request.Body.ReadAsync(buffer, 0, buffer.Length);
            // We convert the byte[] into a string using UTF8 encoding...
            //... and send it back...
            return Encoding.UTF8.GetString(buffer);
        }

希望这能帮助到一些人,因为我在做我的研究时偶然发现了这篇文章以及其他15篇stackoverflow文章