csharp 过滤属性以捕获和记录ASP.NET中的请求和响应
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 过滤属性以捕获和记录ASP.NET中的请求和响应相关的知识,希望对你有一定的参考价值。
public class LoggerFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
HttpRequestBase request = filterContext.HttpContext.Request;
APIAccessLogItem item;
try
{
var controller = filterContext.Controller;
var routeData = request.RequestContext.RouteData;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < request.Headers.Count; i++)
sb.AppendFormat("{0}={1};", request.Headers.Keys[i],
request.Headers[i].ToString());
item = new APIAccessLogItem()
{
RequestDate = DateTime.Now,
RequestType = request.RequestType,
Url = request.RawUrl,
IPAddress = request.UserHostAddress,
Controller = (string)routeData.Values["controller"],
Action = (string)routeData.Values["action"],
RequestHeader = sb.ToString()
};
sb = null;
using (StreamReader reader = new StreamReader(request.InputStream))
{
try
{
request.InputStream.Position = 0;
item.RequestBody = reader.ReadToEnd();
}
catch (Exception ex)
{
item.RequestBody = string.Empty;
//log errors
}
finally
{
request.InputStream.Position = 0;
}
}
filterContext.HttpContext.Response.Filter = new CapturingResponseFilter(filterContext.HttpContext.Response.Filter, item);
}
catch (Exception ex)
{
//log errors
}
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
try
{
HttpResponseBase response = filterContext.HttpContext.Response;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < response.Headers.Count; i++)
sb.AppendFormat("{0}={1};", response.Headers.Keys[i],
response.Headers[i].ToString());
var filter = (CapturingResponseFilter)filterContext.HttpContext.Response.Filter;
var item = filter.AccessLogItem;
item.ResponseDate = DateTime.Now;
item.ResponseHeader = sb.ToString();
sb = null;
}
catch (Exception ex)
{
//log errors
}
}
}
class CapturingResponseFilter : Stream
{
private Stream _sink;
private MemoryStream mem;
public APIAccessLogItem AccessLogItem { get; set; }
public CapturingResponseFilter(Stream sink, APIAccessLogItem item)
{
_sink = sink;
AccessLogItem = item;
mem = new MemoryStream();
}
public override bool CanRead
{
get { return _sink.CanRead; }
}
public override bool CanSeek
{
get { return _sink.CanSeek; }
}
public override bool CanWrite
{
get { return _sink.CanWrite; }
}
public override long Length
{
get { return _sink.Length; }
}
public override long Position
{
get
{
return _sink.Position;
}
set
{
_sink.Position = value;
}
}
public override long Seek(long offset, SeekOrigin direction)
{
return _sink.Seek(offset,direction);
}
public override void SetLength(long length)
{
_sink.SetLength(length);
}
public override void Close()
{
_sink.Close();
mem.Close();
}
public override void Flush()
{
_sink.Flush();
AccessLogItem.ResponseBody = GetContents(new UTF8Encoding(false));
//YOU CAN STORE YOUR DATA TO YOUR DATABASE HERE
}
public override int Read(byte[] buffer, int offset, int count)
{
return _sink.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count)
{
mem.Write(buffer, 0, count);
_sink.Write(buffer, offset, count);
}
public string GetContents(Encoding enc)
{
var buffer = new byte[mem.Length];
mem.Position = 0;
mem.Read(buffer, 0, buffer.Length);
return enc.GetString(buffer, 0, buffer.Length);
}
}
以上是关于csharp 过滤属性以捕获和记录ASP.NET中的请求和响应的主要内容,如果未能解决你的问题,请参考以下文章
来自 ActionFilter 的 ModelState - ASP .NET Core 2.1 API