Я пытаюсь реализовать обработку ошибок в одном из наших ASP. NET веб-API (не основных) проектов (работающих. NET 4.7.2), чтобы в будущем не возникла ошибка, у нас было пару дней go.
Ошибка состояла в том, что этот код в файле Web.Config не был обновлен, но была обновлена библиотека, поставляемая с проектом, когда он был опубликован, поэтому было несовпадение версий.
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701"/>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"/>
</compilers>
</system.codedom>
Version=2.0.1.0
в обеих compiler
строках было установлено на Version=1.0.8.0
, а опубликованная версия DLL была 2.0.1.0. Это дает ошибку, которая выглядит следующим образом:
Теперь я хотел бы обработать это исключение в коде и записать его в наш стек журналирования. , Я искал вокруг и нашел несколько различных методов отлова исключений в проекте web.api, но ни один из них, похоже, не сработал. Я попробовал:
В файле global.asax.cs
:
void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
if (ex != null)
Logger.WriteToFile(ex.Message, ex);
}
Также в файле global.asax.cs
:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = (e.ExceptionObject as Exception);
if (ex != null)
Logger.WriteToFile(ex.Message, ex);
}
В WebApiConfig.Register
функция, которая автоматически добавляется в Web.API (например, которая управляет настройкой маршрутизации):
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Filters.Add(new GlobalExceptionFilterAttribute()); // <-- this line
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
public class GlobalExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
var exceptionType = context.Exception.GetType().ToString();
var exception = context.Exception.InnerException ?? context.Exception;
try
{
if (exception != null)
Logger.WriteToFile(exception.Message, exception);
}
finally
{
base.OnException(context);
}
}
}
И в файле web.config я добавил модуль, который должен (теоретически ) обрабатывать ошибки уровня IIS (взято из Ошибка определения уровня IIS для обработки в ASP. NET):
<system.webServer>
<modules>
<add type="ErrorHttpModule" name="ErrorHttpModule"/>
</modules>
</system.webServer>
public class ErrorHttpModule : IHttpModule
{
private HttpApplication _context;
public ErrorHttpModule() { }
public void Init(HttpApplication context)
{
_context = context;
_context.Error += new EventHandler(ErrorHandler);
}
private void ErrorHandler(object sender, EventArgs e)
{
Exception ex = _context.Server.GetLastError();
if (ex != null)
Logger.WriteToFile(ex.Message, ex);
}
public void Dispose()
{
}
}
И, похоже, ничего из этого не перехватывается ошибка, и зарегистрируйте ее. Как я могу поймать эту ошибку?
Я воспроизвел эту ошибку в совершенно пустом проекте Web.API в дополнение к нашему основному проекту. Пустой проект Web.API можно найти по адресу https://github.com/Loyalar/IISExceptionCapture.