在我的MVC应用程序中,我正在尝试处理Application_Error
HttpApplication
方法中的错误。在那个处理程序中我这样做:
Exception exc = Server.GetLastError();
我正在使用Ninject,它提供了自己的DefaultControllerFactory
,这将为不存在的控制器抛出一个异常,我可以很容易地抓住它:
if (exc is MyApp.Web.App_Start.ControllerNotFoundException)
{
Response.Clear();
Response.StatusCode = (int)System.Net.HttpStatusCode.NotFound;
Server.ClearError();
log = false;
}
哪个效果很好。我不想记录这些。
问题在于控制器确实存在,但操作不存在。例如,我有人打了:admin/config.php
。我实际上有一个AdminController
因此不会导致ControllerNotFoundException
,它会给我一个HttpException
的文字:
"A public action method 'config.php' was not found on controller 'MyApp.Web.Controllers.AdminController'."
但我不是解析文本以检测它是HttpException
这种类型而不是其他类型,有没有办法告诉这是一个未找到的动作而不是其他的动作?
答案 0 :(得分:4)
我相信这会做你想要的。您可以继承默认的AsyncControllerActionInvoker
类,然后将其注入。
public class DependencyResolverForControllerActionInvoker : IDependencyResolver
{
private readonly IDependencyResolver innerDependencyResolver;
public DependencyResolverForControllerActionInvoker(IDependencyResolver innerDependencyResolver)
{
if (innerDependencyResolver == null)
throw new ArgumentNullException("innerDependencyResolver");
this.innerDependencyResolver = innerDependencyResolver;
}
public object GetService(Type serviceType)
{
if (typeof(IAsyncActionInvoker).Equals(serviceType) || typeof(IActionInvoker).Equals(serviceType))
{
return new MyAsyncControllerActionInvoker();
}
return this.innerDependencyResolver.GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.innerDependencyResolver.GetServices(serviceType);
}
}
public class MyAsyncControllerActionInvoker : AsyncControllerActionInvoker
{
public override bool InvokeAction(ControllerContext controllerContext, string actionName)
{
try
{
return base.InvokeAction(controllerContext, actionName);
}
catch (HttpException ex)
{
// Handle unknown action error
}
}
public override bool EndInvokeAction(IAsyncResult asyncResult)
{
try
{
return base.EndInvokeAction(asyncResult);
}
catch (HttpException ex)
{
// Handle unknown action error
}
}
}
以下是InvokeAction和EndInvokeAction方法的链接,因此您可以尝试确定如何最好地处理它引发的任何错误。
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// Decorate the current dependency resolver
// (make sure to do this last if using a DI container -
// or alternatively register your type with the DI container)
DependencyResolver.SetResolver(
new DependencyResolverForControllerActionInvoker(DependencyResolver.Current));
}
}
您可以创建一个基本控制器并覆盖HandleUnknownAction
方法以获得类似(但更紧密耦合)的结果。