在 .net 核心 web 中使用 AOP 记录异常 api
Logging Exception using AOP in .netcore web api
我有一个 web api 项目正在进行中,我想使用记录器将我在 web api 中的所有控制器记录到一个文件中。
[HttpGet]
[Route("")]
public IActionResult GetAllDocumentTempates()
{
try
{
var document = _doumentTemplate.GetLiteDocumentReportTemplates().ToList();
var result = Mapper.Map<IEnumerable<LiteDocumentReportTemplateViewModel>>(document);
return Ok(result);
}
catch (Exception ex)
{
String msgInnerExAndStackTrace = string.Format("{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(string.Format("From frmDelivery.ConditionallyPrint():{0}", msgInnerExAndStackTrace));
return BadRequest();
}
}
This is my ExceptionLoggingService.cs:
这是为我处理所有错误并记录到文件的服务
public class ExceptionLoggingService: ActionFilterAttribute
{
// </ Singleton code
// private fields
private readonly FileStream _fileStream;
private readonly StreamWriter _streamWriter;
private static ExceptionLoggingService _instance;
// public property
public static ExceptionLoggingService Instance
{
get
{
return _instance ?? (_instance = new ExceptionLoggingService());
}
}
//private constructor
private ExceptionLoggingService()
{
_fileStream = File.OpenWrite(GetExecutionFolder() + "\EasyAsFallingOffA.log");
_streamWriter = new StreamWriter(_fileStream);
}
// <!-- Singleton code
public void WriteLog(string message)
{
if (!HHSConsts.Logging) return;
StringBuilder formattedMessage = new StringBuilder();
formattedMessage.AppendLine("Date: " + DateTime.Now.ToString());
formattedMessage.AppendLine("Message: " + message);
_streamWriter.WriteLine(formattedMessage.ToString());
_streamWriter.Flush();
}
private string GetExecutionFolder()
{
return Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
}
}
这是我的EasyAsFallingOffA.log
文件输出
Date: 6/23/2018 12:02:24 PM
Message: From frmDelivery.ConditionallyPrint():Object reference not set to an instance of an object.; Inner Ex: ; Stack Trace: at ProcessFlowManager.Domain.Helpers.ModelFactory.Create(CalendarActivity cal) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.Domain\Helpers\ModelFactory.cs:line 1170
at ProcessFlowManager.Infrastructure.LogicImplementations.EfCalendarActivities.GetCalendarActivity(Int32 id) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.Infrastructure\LogicImplementations\EfCalendarActivities.cs:line 54
at ProcessFlowManager.API.Controllers.CalendarController.GetAllGeneratedDcument(Int32 id) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.API\Controllers\CalendarController.cs:line 79
以上所有代码一切正常,但所有这些代码都是使用重言式实现的,因为我在所有尝试和捕获中重复。我是 AOP 的新手,正在寻找一种使用 AOP 执行此操作的方法,这样我就可以在我的控制器中调用它一次。
您可以使用此 link 开始:
Aspect Oriented Programming Using C# and PostSharp
或者这个:
Injecting Behaviors Before and After Method Execution
一级:
1) 使用命名的 LoggingAspect
添加 Class 您的项目
2) 继承OnMethodBoundaryAspect
3)所以实现OnEntry,OnSuccess,OnExit,OnException
喜欢下面的代码:
[PSerializable]
public class LoggingAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine("The {0} method has been entered.", args.Method.Name);
}
public override void OnSuccess(MethodExecutionArgs args)
{
Console.WriteLine("The {0} method executed successfully.", args.Method.Name);
}
public override void OnExit(MethodExecutionArgs args)
{
Console.WriteLine("The {0} method has exited.", args.Method.Name);
}
public override void OnException(MethodExecutionArgs args)
{
Console.WriteLine("An exception was thrown in {0}.", args.Method.Name);
}
}
static class Program
{
[LoggingAspect]
static void Main()
{
Console.WriteLine("Hello, world.");
}
}
输出:
The Main method has been entered.
Hello, world.
The Main method executed successfully.
The Main method has exited.
在互联网上进行了大量的尝试以找到我的问题的答案之后,我已经成功地记录了我所有的异常,而没有使用像 PostSharp、Log4File、Spring 等第三方库。
使用
ActionFilterAttribute, IExceptionFilter
我能够解决这个问题并使用以下代码记录企业项目的所有异常
public class LatestErrorHandler : ActionFilterAttribute, IExceptionFilter
{
private const string FILE_NAME = "Exception.log";
private const string TRACE_FILE = "TraceLog.log";
public Type _exceptionType;
FileStream _fileStream;
StreamWriter _streamWriter;
IHostingEnvironment host;
public LatestErrorHandler(Type exceptionType)
{
// _fileStream = File.OpenWrite(host.ContentRootPath + "\wale.log");
//_streamWriter = new StreamWriter(_fileStream);
//_fileStream.Close();
_exceptionType = exceptionType;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
using (FileStream fs=new FileStream(TRACE_FILE, FileMode.Append, FileAccess.Write))
{
using (BinaryWriter rite=new BinaryWriter(fs))
{
if (context.HttpContext.Response==null)
{
string con = "No log";
rite.Write(con);
}
else
{
Controller exValue = (Controller)context.Controller;
ControllerContext control = (ControllerContext)exValue.ControllerContext;
///HttpMethodActionConstraint http = (HttpMethodActionConstraint)control.ActionDescriptor.ActionConstraints.;
rite.Write(
" Date Exception Occurred" + DateTime.Now.ToString() +
" Route "
+control.RouteData.DataTokens.Values
+context.RouteData.Routers
//+control.ActionDescriptor.ActionConstraints+ ":"+ http.HttpMethods
+ context.RouteData.Values.Keys
+ control.ActionDescriptor.ActionName
+context.ActionDescriptor.RouteValues.Values+
" Parameter"
+ context.ActionDescriptor.Parameters
+context.ActionDescriptor.Properties+
" Controller"
+ control.ActionDescriptor.ControllerName
);
}
}
}
}
public void OnException(ExceptionContext context)
{
var cont= context.Exception;
//var contInner = context.Exception.InnerException;
using (FileStream fs = new FileStream(FILE_NAME, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (BinaryWriter rite = new BinaryWriter(fs))
{
// context.Result actionResult = new context.Result();
if (context.HttpContext.Response == null)
{
string con = "no errroer ";
rite.Write(con);
}
else
{
rite.Write(
"Date Exception Occurred" + DateTime.Now.ToString() +
" Exceptions" + "Message: " + cont.Message +
" InnerException" + cont.InnerException +
" StackTrace" + cont.StackTrace+
"Response" + context.HttpContext.Response.StatusCode
);
}
}
}
}
public override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
var cont = context.Exception;
//var contInner = context.Exception.InnerException;
using (FileStream fs = new FileStream(FILE_NAME, FileMode.Append, FileAccess.Write))
{
using (BinaryWriter rite=new BinaryWriter(fs))
{
// context.Result actionResult = new context.Result();
var type = context.Result.GetType().Name; //context.Result
if(type == "BadRequestObjectResult" )
{
BadRequestObjectResult cont2 = (BadRequestObjectResult)context.Result;
Exception exValue = (Exception) cont2.Value;
if (exValue.InnerException==null)
{
rite.Write(
"\n Date Exception Occurred " + DateTime.Now.ToString() +
"\n Exceptions" + "Message: " + cont2.Value +
// "\n InnerException " + exValue.InnerException +
"\n Message " + exValue.Message +
"\n StackTrace " + exValue.StackTrace
//"Response" + context.HttpContext.Response.StatusCode
);
}
else
{
rite.Write(
"\n Date Exception Occurred " + DateTime.Now.ToString() +
"\n Exceptions" + "Message: " + cont2.Value +
"\n InnerException " + exValue.InnerException +
"\n Message " + exValue.Message +
"\n StackTrace " + exValue.StackTrace
//"Response" + context.HttpContext.Response.StatusCode
);
}
}
else
{
// log details without error.
}
}
}
}
}
通过这个 class 我使用面向方面编程 (AOP) 成功地将我所有的异常记录到我所有控制器中的文件中。
[LatestErrorHandler(typeof(ExceptionContext))]
//[CustomLoggingAttirbute]
[Produces("application/json")]
[Route("api/Calendar")]
public class CalendarController : Controller
{
ICalendarActivities calendarActivities;
IHostingEnvironment IHostingEnvironment;
string projectFolder = "";
string fileRootPath = "";
// private string projectRootFolder;
public CalendarController(ICalendarActivities _calendarActivities)
{
calendarActivities = _calendarActivities;
}
[HttpGet]
[Route("")]
public IActionResult GetAllCalenderReportList()
{
try
{
var calendars = calendarActivities.GetCalendarActivities();
var result = AutoMapper.Mapper.Map<IEnumerable<LiteCalendarViewModel>>(calendars);
return Ok(result);
}
catch (Exception ex)
{
//string msginnerexandstacktrace = string.Format("{0}; inner ex: {1}; stack trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
//ExceptionLoggingService.Instance.WriteLog(string.Format("from frmdelivery.conditionallyprint():{0}", msginnerexandstacktrace));
return BadRequest(ex);
}
}
这是我的输出
Date Exception Occurred 7/2/2018 5:13:18 PM
ExceptionsMessage: System.NullReferenceException: Object reference not set to an instance of an object.
at ProcessFlowManager.Domain.Helpers.ModelFactory.Create(CalendarActivity cal) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.Domain\Helpers\ModelFactory.cs:line 1170
at ProcessFlowManager.Infrastructure.LogicImplementations.EfCalendarActivities.GetCalendarActivity(Int32 id) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.Infrastructure\LogicImplementations\EfCalendarActivities.cs:line 48
at ProcessFlowManager.API.Controllers.CalendarController.GetAllGeneratedDcument(Int32 id) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.API\Controllers\CalendarController.cs:line 83
InnerException
Message Object reference not set to an instance of an object.
StackTrace at ProcessFlowManager.Domain.Helpers.ModelFactory.Create(CalendarActivity cal) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.Domain\Helpers\ModelFactory.cs:line 1170
我有一个 web api 项目正在进行中,我想使用记录器将我在 web api 中的所有控制器记录到一个文件中。
[HttpGet]
[Route("")]
public IActionResult GetAllDocumentTempates()
{
try
{
var document = _doumentTemplate.GetLiteDocumentReportTemplates().ToList();
var result = Mapper.Map<IEnumerable<LiteDocumentReportTemplateViewModel>>(document);
return Ok(result);
}
catch (Exception ex)
{
String msgInnerExAndStackTrace = string.Format("{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(string.Format("From frmDelivery.ConditionallyPrint():{0}", msgInnerExAndStackTrace));
return BadRequest();
}
}
This is my ExceptionLoggingService.cs:
这是为我处理所有错误并记录到文件的服务
public class ExceptionLoggingService: ActionFilterAttribute
{
// </ Singleton code
// private fields
private readonly FileStream _fileStream;
private readonly StreamWriter _streamWriter;
private static ExceptionLoggingService _instance;
// public property
public static ExceptionLoggingService Instance
{
get
{
return _instance ?? (_instance = new ExceptionLoggingService());
}
}
//private constructor
private ExceptionLoggingService()
{
_fileStream = File.OpenWrite(GetExecutionFolder() + "\EasyAsFallingOffA.log");
_streamWriter = new StreamWriter(_fileStream);
}
// <!-- Singleton code
public void WriteLog(string message)
{
if (!HHSConsts.Logging) return;
StringBuilder formattedMessage = new StringBuilder();
formattedMessage.AppendLine("Date: " + DateTime.Now.ToString());
formattedMessage.AppendLine("Message: " + message);
_streamWriter.WriteLine(formattedMessage.ToString());
_streamWriter.Flush();
}
private string GetExecutionFolder()
{
return Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
}
}
这是我的EasyAsFallingOffA.log
文件输出
Date: 6/23/2018 12:02:24 PM Message: From frmDelivery.ConditionallyPrint():Object reference not set to an instance of an object.; Inner Ex: ; Stack Trace: at ProcessFlowManager.Domain.Helpers.ModelFactory.Create(CalendarActivity cal) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.Domain\Helpers\ModelFactory.cs:line 1170 at ProcessFlowManager.Infrastructure.LogicImplementations.EfCalendarActivities.GetCalendarActivity(Int32 id) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.Infrastructure\LogicImplementations\EfCalendarActivities.cs:line 54 at ProcessFlowManager.API.Controllers.CalendarController.GetAllGeneratedDcument(Int32 id) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.API\Controllers\CalendarController.cs:line 79
以上所有代码一切正常,但所有这些代码都是使用重言式实现的,因为我在所有尝试和捕获中重复。我是 AOP 的新手,正在寻找一种使用 AOP 执行此操作的方法,这样我就可以在我的控制器中调用它一次。
您可以使用此 link 开始: Aspect Oriented Programming Using C# and PostSharp
或者这个: Injecting Behaviors Before and After Method Execution
一级:
1) 使用命名的 LoggingAspect
添加 Class 您的项目2) 继承OnMethodBoundaryAspect
3)所以实现OnEntry,OnSuccess,OnExit,OnException
喜欢下面的代码:
[PSerializable]
public class LoggingAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine("The {0} method has been entered.", args.Method.Name);
}
public override void OnSuccess(MethodExecutionArgs args)
{
Console.WriteLine("The {0} method executed successfully.", args.Method.Name);
}
public override void OnExit(MethodExecutionArgs args)
{
Console.WriteLine("The {0} method has exited.", args.Method.Name);
}
public override void OnException(MethodExecutionArgs args)
{
Console.WriteLine("An exception was thrown in {0}.", args.Method.Name);
}
}
static class Program
{
[LoggingAspect]
static void Main()
{
Console.WriteLine("Hello, world.");
}
}
输出:
The Main method has been entered.
Hello, world.
The Main method executed successfully.
The Main method has exited.
在互联网上进行了大量的尝试以找到我的问题的答案之后,我已经成功地记录了我所有的异常,而没有使用像 PostSharp、Log4File、Spring 等第三方库。 使用
ActionFilterAttribute, IExceptionFilter
我能够解决这个问题并使用以下代码记录企业项目的所有异常
public class LatestErrorHandler : ActionFilterAttribute, IExceptionFilter
{
private const string FILE_NAME = "Exception.log";
private const string TRACE_FILE = "TraceLog.log";
public Type _exceptionType;
FileStream _fileStream;
StreamWriter _streamWriter;
IHostingEnvironment host;
public LatestErrorHandler(Type exceptionType)
{
// _fileStream = File.OpenWrite(host.ContentRootPath + "\wale.log");
//_streamWriter = new StreamWriter(_fileStream);
//_fileStream.Close();
_exceptionType = exceptionType;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
using (FileStream fs=new FileStream(TRACE_FILE, FileMode.Append, FileAccess.Write))
{
using (BinaryWriter rite=new BinaryWriter(fs))
{
if (context.HttpContext.Response==null)
{
string con = "No log";
rite.Write(con);
}
else
{
Controller exValue = (Controller)context.Controller;
ControllerContext control = (ControllerContext)exValue.ControllerContext;
///HttpMethodActionConstraint http = (HttpMethodActionConstraint)control.ActionDescriptor.ActionConstraints.;
rite.Write(
" Date Exception Occurred" + DateTime.Now.ToString() +
" Route "
+control.RouteData.DataTokens.Values
+context.RouteData.Routers
//+control.ActionDescriptor.ActionConstraints+ ":"+ http.HttpMethods
+ context.RouteData.Values.Keys
+ control.ActionDescriptor.ActionName
+context.ActionDescriptor.RouteValues.Values+
" Parameter"
+ context.ActionDescriptor.Parameters
+context.ActionDescriptor.Properties+
" Controller"
+ control.ActionDescriptor.ControllerName
);
}
}
}
}
public void OnException(ExceptionContext context)
{
var cont= context.Exception;
//var contInner = context.Exception.InnerException;
using (FileStream fs = new FileStream(FILE_NAME, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (BinaryWriter rite = new BinaryWriter(fs))
{
// context.Result actionResult = new context.Result();
if (context.HttpContext.Response == null)
{
string con = "no errroer ";
rite.Write(con);
}
else
{
rite.Write(
"Date Exception Occurred" + DateTime.Now.ToString() +
" Exceptions" + "Message: " + cont.Message +
" InnerException" + cont.InnerException +
" StackTrace" + cont.StackTrace+
"Response" + context.HttpContext.Response.StatusCode
);
}
}
}
}
public override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
var cont = context.Exception;
//var contInner = context.Exception.InnerException;
using (FileStream fs = new FileStream(FILE_NAME, FileMode.Append, FileAccess.Write))
{
using (BinaryWriter rite=new BinaryWriter(fs))
{
// context.Result actionResult = new context.Result();
var type = context.Result.GetType().Name; //context.Result
if(type == "BadRequestObjectResult" )
{
BadRequestObjectResult cont2 = (BadRequestObjectResult)context.Result;
Exception exValue = (Exception) cont2.Value;
if (exValue.InnerException==null)
{
rite.Write(
"\n Date Exception Occurred " + DateTime.Now.ToString() +
"\n Exceptions" + "Message: " + cont2.Value +
// "\n InnerException " + exValue.InnerException +
"\n Message " + exValue.Message +
"\n StackTrace " + exValue.StackTrace
//"Response" + context.HttpContext.Response.StatusCode
);
}
else
{
rite.Write(
"\n Date Exception Occurred " + DateTime.Now.ToString() +
"\n Exceptions" + "Message: " + cont2.Value +
"\n InnerException " + exValue.InnerException +
"\n Message " + exValue.Message +
"\n StackTrace " + exValue.StackTrace
//"Response" + context.HttpContext.Response.StatusCode
);
}
}
else
{
// log details without error.
}
}
}
}
}
通过这个 class 我使用面向方面编程 (AOP) 成功地将我所有的异常记录到我所有控制器中的文件中。
[LatestErrorHandler(typeof(ExceptionContext))]
//[CustomLoggingAttirbute]
[Produces("application/json")]
[Route("api/Calendar")]
public class CalendarController : Controller
{
ICalendarActivities calendarActivities;
IHostingEnvironment IHostingEnvironment;
string projectFolder = "";
string fileRootPath = "";
// private string projectRootFolder;
public CalendarController(ICalendarActivities _calendarActivities)
{
calendarActivities = _calendarActivities;
}
[HttpGet]
[Route("")]
public IActionResult GetAllCalenderReportList()
{
try
{
var calendars = calendarActivities.GetCalendarActivities();
var result = AutoMapper.Mapper.Map<IEnumerable<LiteCalendarViewModel>>(calendars);
return Ok(result);
}
catch (Exception ex)
{
//string msginnerexandstacktrace = string.Format("{0}; inner ex: {1}; stack trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
//ExceptionLoggingService.Instance.WriteLog(string.Format("from frmdelivery.conditionallyprint():{0}", msginnerexandstacktrace));
return BadRequest(ex);
}
}
这是我的输出
Date Exception Occurred 7/2/2018 5:13:18 PM ExceptionsMessage: System.NullReferenceException: Object reference not set to an instance of an object. at ProcessFlowManager.Domain.Helpers.ModelFactory.Create(CalendarActivity cal) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.Domain\Helpers\ModelFactory.cs:line 1170 at ProcessFlowManager.Infrastructure.LogicImplementations.EfCalendarActivities.GetCalendarActivity(Int32 id) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.Infrastructure\LogicImplementations\EfCalendarActivities.cs:line 48 at ProcessFlowManager.API.Controllers.CalendarController.GetAllGeneratedDcument(Int32 id) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.API\Controllers\CalendarController.cs:line 83 InnerException
Message Object reference not set to an instance of an object. StackTrace at ProcessFlowManager.Domain.Helpers.ModelFactory.Create(CalendarActivity cal) in C:\Users\BABATUNDE\Documents\Visual Studio 2017\Projects\pcm-netcore\ProcessFlowManager.Domain\Helpers\ModelFactory.cs:line 1170