c# - 有没有办法在 ASP.NET Web API REST 服务中执行一次代码?
问题描述
我有一个 ASP.NET Web API REST 服务,我想在服务第一次启动时执行一些代码,而不是每次从我的 ASP.NET MVC 应用程序请求/调用 Web api 方法时。
我想这样做是因为我想初始化一个 EventLog,然后用它在 windows 事件查看器中创建条目。
有什么简单的方法吗?
更新:正如 Jonhatan 在他的回答中建议的那样,我在 global.asax.cs 中创建了一个方法:
全球.asax.cs:
namespace MyWebAPIApp
{
public class WebApiApplication : System.Web.HttpApplication
{
public MyLog _myLog;
protected void Application_Start()
{
// Here some stuff
SetupEventLogging();
}
private void SetupEventLogging()
{
if (!EventLog.SourceExists("MyWebApiLog"))
{
EventLog.CreateEventSource("MyWebApiLog", "MyWebApiLogLog");
}
EventLog eventLog = new EventLog();
eventLog.Source = "MyWebApiLog";
eventLog.Log = "MyWebApiLog";
_myLog = new MyLog(eventLog, "MyWebApiService");
}
}
}
控制器:
namespace MyWebAPIApp.Controllers
{
public class MyController : ApiController
{
public void GetAll()
{
_myLog.Success("All records read");
}
}
}
但是现在如果我创建了一个全局变量 _myLog,我怎样才能从我的 Controller 中的所有方法访问这个变量以执行 _myLog.Error(...) 或 _myLog.Success(...)?
解决方案
您通常会ApplicationStart
在 global.asax.cs 中的方法中执行此操作:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
SetupLogging(); // do something in here / wire up your flavour of logging
}
通常,模式将是:
- 在应用程序启动时设置您的日志记录 - 这是您设置数据库连接以存储日志等的地方
logger.Write
只要您想写入日志,就在整个代码中调用静态方法。
我使用 Microsoft.Practices.EnterpriseLibrary.Logging,但我认为 Serilog 或 Log4Net 现在可能是两种更常见的框架。
所以,在我的 global.asax.cs 中,SetupLogging()
方法是:
private static void SetupLogging()
{
var configurationSource = ConfigurationSourceFactory.Create();
DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory(configurationSource));
var logWriterFactory = new LogWriterFactory(configurationSource);
Logger.SetLogWriter(logWriterFactory.Create());
var daysToKeepLogsInDb = int.Parse(ConfigurationManager.AppSettings["DaysToKeepLogsInDb"]);
CustomLogger.PurgeLogs(daysToKeepLogsInDb); // only keep last 90 etc days of event logging in the db
CustomLogger.Write("Application Starting", TraceEventType.Information);
}
基本上只是框架需要“开始”的东西,以及一些自定义清理。然后我有一个CustomLogger
类来帮助按照我想要的方式编写条目,运行自定义存储过程来清理旧日志等:
using Microsoft.Practices.EnterpriseLibrary.Logging;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
namespace MyApplication.Helpers
{
public class CustomLogger
{
private static readonly ICollection<string> EmptyCategoriesList = new List<string>(0);
private const string LogTitle = "MyApplication Name";
public static void Write(object message)
{
Write(message, TraceEventType.Error);
}
public static void Write(object message, TraceEventType severity)
{
Logger.Write(message, EmptyCategoriesList, -1, 1, severity, LogTitle);
}
public static void PurgeLogs(int keepLastXDays)
{
var connectionString = ConfigurationManager.ConnectionStrings["MyLoggingConnectionString"].ConnectionString;
using (var con = new SqlConnection(connectionString))
{
using (var command = new SqlCommand("PurgeLogs", con)) // custom stored procedure
{
var dateTo = DateTime.Now.AddDays(keepLastXDays * -1);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@dateTo", dateTo));
command.Parameters.Add(new SqlParameter("@title", LogTitle));
con.Open();
command.ExecuteNonQuery();
con.Close(); // technically not required because in using, but leaving in case this block gets copy-pasted out of here
}
}
}
}
}
然后,在我的代码(控制器、助手等)中,我通过自定义记录器中的静态方法写入日志:
public static void EndSession(Session session)
{
try
{
Logon.DoLogoff(session);
}
catch (Exception exception)
{
CustomLogger.Write(exception);
throw new Exception("Error ending session.");
}
}
如果您使用依赖注入来执行此操作,它将(特别是)允许您更轻松地更换日志框架,并允许您更轻松地进行单元测试。但是您必须在应用程序和记录器之间创建另一个“层”以进一步抽象关系。您应该阅读依赖注入,因为它通常值得使用。
推荐阅读
- docker - 如何将多个(子)域绑定到 docker 中的一个容器,在 traefik 中具有不同的端口
- jquery - jquery数据表排序按钮在标题列中不可用
- javascript - 在我的函数中构建我的条件不起作用。程序不想执行我的条件?
- android - Android 服务未从 Activity 启动
- php - 网络表单记录需要 csv 文件和文件特定的电子邮件
- javascript - 带有 3D 旋转物体的旋转木马
- datastax - DataStax - OpsCenter LifeCycle Manager(无法启动 LSB:DataStax Enterprise)
- ios - 如何使用设备检查标记黑客
- android - 在运行周期性任务之前立即运行工作 - WorkManager
- ms-access - 当 Access 屏幕的其余部分被隐藏时,如何在 ac.preview 视图中显示 Access 报告?