Mik*_*oud 16 c# asp.net-mvc exception-handling automapper asp.net-mvc-4
我有一个名为的全局异常过滤器LogErrorAttribute
:
public class LogErrorAttribute : IExceptionFilter
{
private ILogUtils logUtils;
public void OnException(ExceptionContext filterContext)
{
if (this.logUtils == null)
{
this.logUtils = StructureMapConfig.Container.GetInstance<ILogUtils>();
}
this.logUtils.LogError(HttpContext.Current.User.Identity.GetUserId(), "Unknown error.", filterContext.Exception);
}
}
Run Code Online (Sandbox Code Playgroud)
它与标准HandleErrorAttribute
过滤器一起注册:
filters.Add(new LogErrorAttribute());
filters.Add(new HandleErrorAttribute());
Run Code Online (Sandbox Code Playgroud)
我正在注册这样的过滤器:
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
Run Code Online (Sandbox Code Playgroud)
我也有一个Application_Error
后备:
protected void Application_Error()
{
var exception = Server.GetLastError();
Server.ClearError();
var httpException = exception as HttpException;
//Logging goes here
var routeData = new RouteData();
routeData.Values["controller"] = "Error";
routeData.Values["action"] = "Index";
if (httpException != null)
{
if (httpException.GetHttpCode() == 404)
{
routeData.Values["action"] = "NotFound";
}
Response.StatusCode = httpException.GetHttpCode();
}
else
{
Response.StatusCode = 500;
}
// Avoid IIS7 getting involved
Response.TrySkipIisCustomErrors = true;
// Execute the error controller
if (exception != null)
{
this.errorLogger.Log(LogLevel.Error, "An unknown exception has occurred.", exception);
}
else if (httpException != null)
{
this.errorLogger.Log(LogLevel.Error, "An unknown HTTP exception has occurred.", httpException);
}
else
{
this.errorLogger.Log(LogLevel.Error, "An unknown error has occurred.");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我有一个API控制器,它从数据库中获取一些数据,然后用于AutoMapper
映射模型以查看模型:
var viewModels = AutoMapper.Mapper.Map(users, new List<UserViewModel>());
Run Code Online (Sandbox Code Playgroud)
在该AutoMapper
配置中,为其中一个属性执行自定义解析程序:
var appModuleAssignments = this.appModuleAssignmentManager.Get(userId);
var appModules = appModuleAssignments.Select(x => this.appModuleManager.Get(x.AppModuleId));
return AutoMapper.Mapper.Map(appModules, new List<AppModuleViewModel>());
Run Code Online (Sandbox Code Playgroud)
目前我正在强制appModuleManager.Get
声明抛出常规异常:
throw new Exception("Testing global filter.");
Run Code Online (Sandbox Code Playgroud)
这随后抛出异常AutoMapper
,两者都未处理,但全局过滤器或Application_Error
正在拾取此异常.
我在这做错了什么?
自发布以来我做过的几件事情:
customErrors
属性Web.config
以转动它们on
.HandleErrorAttribute
全局过滤器,因为我意识到它正在设置错误,如果它甚至正在运行.我不希望它仍然在执行,因为这个错误发生在控制器外部,但它可能会在稍后发生.简短的回答是您要添加MVC异常过滤器而不是Web API异常过滤器.
您的实施检查ExceptionContext
而不是HttpActionExecutedContext
public override void OnException(HttpActionExecutedContext actionExecutedContext)
Run Code Online (Sandbox Code Playgroud)
由于框架将引发Http异常而不是MVC异常,OnException
因此不会触发覆盖方法.
所以,一个更完整的例子:
public class CustomExceptionFilter : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
message = "Web API Error";
status = HttpStatusCode.InternalServerError;
actionExecutedContext.Response = new HttpResponseMessage()
{
Content = new StringContent(message, System.Text.Encoding.UTF8, "text/plain"),
StatusCode = status
};
base.OnException(actionExecutedContext);
}
}
Run Code Online (Sandbox Code Playgroud)
另一个重要步骤是在Register(HttpConfiguration config)
方法中的WebApiConfig.cs中注册Global Web API异常过滤器.
public static void Register(HttpConfiguration config)
{
...
config.Filters.Add(new CustomExceptionFilter());
}
Run Code Online (Sandbox Code Playgroud)