我把外部括在括号中,但并不完全正确。这是解释:
我有一个MVC ASP.NET应用程序(一个解决方案),它包含以下项目:
前端取决于webapi项目,前端的RouteConfig为webapi项目注册自己和的路由:
//register frontend routes, default code
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
//calls webapi project to register its routes:
//var config = GlobalConfiguration.Configuration;
//... call webApi project
config.Routes.MapHttpRoute(
name: "AppDefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "AppCustomApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
在此配置中,我可以部署并运行前端和访问功能,如下所示:
现在我在注册WebApi项目中发生的异常时遇到了问题。错误和异常处理在FrontEndProject中完美运行:
我可以通过各种方式捕获这些异常和错误(目前我使用HttpModule的自定义实现)
现在,这是一个问题。对WebApi项目的调用不能处理异常和错误。 (http://server/application/api/..)。在浏览器中,我收到正确的回复,例如尝试调用不存在的方法结果: 在调试输出中:
AuditModule: 2016-05-04 14:15:45,201 [56] INFO AuditModule [(null)] - Request::begin
iisexpress.exe Information: 0 : Request, Method=GET, Url=http://localhost:52258/api/controller_name/fake_method, Message='http://localhost:52258/api/controller_name/fake_method'
iisexpress.exe Information: 0 : Message='controller_name', Operation=DefaultHttpControllerSelector.SelectController
iisexpress.exe Information: 0 : Message='Application.Controllers.controller_nameController', Operation=DefaultHttpControllerActivator.Create
iisexpress.exe Information: 0 : Message='Application.Controllers.controller_nameController', Operation=HttpControllerDescriptor.CreateController
iisexpress.exe Information: 0 : Message='Will use same 'JsonMediaTypeFormatter' formatter', Operation=JsonMediaTypeFormatter.GetPerRequestFormatterInstance
iisexpress.exe Information: 0 : Message='Selected formatter='JsonMediaTypeFormatter', content-type='application/json; charset=utf-8'', Operation=DefaultContentNegotiator.Negotiate
iisexpress.exe Warning: 0 : Message='UserMessage='No HTTP resource was found that matches the request URI 'http://localhost:52258/api/controller_name/fake_method'.', MessageDetail='No action was found on the controller 'controller_name' that matches the request.'', Operation=ApiControllerActionSelector.SelectAction, Status=404 (NotFound), Exception=System.Web.Http.HttpResponseException: Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for deta
at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)
at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)
at System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.<>c__DisplayClass2.<System.Web.Http.Controllers.IHttpActionSelector.SelectAction>b__0()
at System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter traceWriter, HttpRequestMessage request, String category, TraceLevel level, String operatorName, String operationName, Action`1 beginTrace, Action execute, Action`1 endTrace, Action`1 errorTrace)
iisexpress.exe Warning: 0 : Message='UserMessage='No HTTP resource was found that matches the request URI 'http://localhost:52258/api/controller_name/fake_method'.', MessageDetail='No action was found on the controller 'controller_name' that matches the request.'', Operation=controller_nameController.ExecuteAsync, Status=404 (NotFound), Exception=System.Web.Http.HttpResponseException: Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for deta
at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)
at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)
at System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.<>c__DisplayClass2.<System.Web.Http.Controllers.IHttpActionSelector.SelectAction>b__0()
at System.Web.Http.Tracing.ITraceWriterExtensions.TraceBeginEnd(ITraceWriter traceWriter, HttpRequestMessage request, String category, TraceLevel level, String operatorName, String operationName, Action`1 beginTrace, Action execute, Action`1 endTrace, Action`1 errorTrace)
at System.Web.Http.Tracing.Tracers.HttpActionSelectorTracer.System.Web.Http.Controllers.IHttpActionSelector.SelectAction(HttpControllerContext controllerContext)
at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
at System.Web.Http.Tracing.Tracers.HttpControllerTracer.<ExecuteAsyncCore>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Tracing.ITraceWriterExtensions.<TraceBeginEndAsyncCore>d__18`1.MoveNext()
iisexpress.exe Information: 0 : Response, Status=404 (NotFound), Method=GET, Url=http://localhost:52258/api/controller_name/fake_method, Message='Content-type='application/json; charset=utf-8', content-length=unknown'
iisexpress.exe Information: 0 : Operation=JsonMediaTypeFormatter.WriteToStreamAsync
iisexpress.exe Information: 0 : Operation=controller_nameController.Dispose
AuditModule: 2016-05-04 14:15:45,236 [56] INFO AuditModule [(null)] - Request::end
The thread 0x6398 has exited with code 0 (0x0).
并在浏览器中(正确的http响应代码,在这种情况下为404):
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:52258/api/controller_name/fake_method'.",
"MessageDetail": "No action was found on the controller 'controller_name' that matches the request."
}
我试过了:
最初的问题来自要求对应用程序中发生的所有事情留下精细的审计跟踪 - 在前端和API中发生的所有成功和失败的请求。我正在使用Log4net来记录这些(和其他)事件。
因此是我的问题 - 任何人都可以提出另一种方法来在此配置中注册所有例外(代码内,http)或指出问题可能来自何处?
谢谢!
upd 1: 我可以通过标准捕获in-code(当我在WebApi方法中抛出异常时): GlobalConfiguration.Configuration.Filters.Add(new CustomExceptionFilterAttribute());
upd 2: 如果我执行以下操作:
public class MyExceptionFilter : IExceptionFilter {...}
GlobalConfiguration.Configuration.Filters.Add(new MyExceptionFilter ());
然后不调用MyExceptionFilter。但是,会调用ExceptionFilterAttribute的impl。
然后我留下的是如何捕获http(WebApi的错误路径)和框架(不可解析的参数等)错误和异常。
upd3:解决了。以下是我的解决方案的步骤。不幸的是,解决方案有点脆弱,需要一定的init步骤序列,而不是太容易出错:
在Application_Start中,在注册任何路由之前:
GlobalConfiguration.Configuration.Services.Add(typeof(IExceptionLogger),new AuditExceptionLogger());
注册前端路线
注册404处理程序并创建错误控制器
RouteTable.Routes.MapHttpRoute( 名称:“Error404”, routeTemplate:“{* url}”, 默认值:new {controller =“Error”,action =“Handle404”} );
实现DefaultHttpControllerSelector和ApiControllerActionSelector,在那里捕获异常并替换为
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),new HttpNotFoundAwareDefaultHttpControllerSelector(GlobalConfiguration.Configuration)); GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionSelector),new HttpNotFoundAwareControllerActionSelector());
我还没有设计CustomError处理 - 我想向无效的前端请求显示正确的错误页面