在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(?

您通常会在global.asax.cs:中的ApplicationStart方法中执行此操作

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
}

通常,模式是:

  1. 在应用程序启动时设置日志记录-这是您设置数据库连接以存储日志等的地方
  2. 每当您想写入日志时,在整个代码中调用一个静态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.");
}
}

如果您使用依赖项注入来实现这一点,它将(尤其(允许您更容易地交换日志框架,并允许您更轻松地进行单元测试。但是,您必须在应用程序和记录器之间创建另一个"层",以便进一步抽象出关系。您应该阅读依赖项注入,因为它通常值得使用。

但是现在如果我创建了一个全局变量_myLog,我如何从我的控制器中的所有方法访问这个变量,以便执行_myLog.Error(…(或_myLog.Success(..(?

使_myLog为静态并引用它WebApiApplication._myLog,其中WebApiApplication是在global.asax.cs中定义的应用程序类。

我宁愿创建一些带有MyLog静态属性的静态类:

public static class LogManager
{
public static MyLog Logger;
}

并且在global.asax.cs中在SetupEventLogging()中放入

LogManager.Logger = new MyLog(eventLog, "MyWebApiService");

最新更新