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);
}
请求流可能已经到达终点。尝试将流位置重置到起始位置:
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文章