C# 在控制器上找不到捕获操作方法

C# 在控制器上找不到捕获操作方法,c#,asp.net-mvc,C#,Asp.net Mvc,在我的MVC应用程序中,我试图处理我的应用程序\u Error方法中的错误。在该处理程序中,我执行以下操作: Exception exc = Server.GetLastError(); 我正在使用Ninject,它提供了自己的DefaultControllerFactory,它将为不存在的控制器抛出一个异常,我可以很容易地捕捉到这样的异常: if (exc is MyApp.Web.App_Start.ControllerNotFoundException) { Response.C

在我的MVC应用程序中,我试图处理我的
应用程序\u Error
方法中的错误。在该处理程序中,我执行以下操作:

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
,而不是其他类型的,有没有办法告诉我们这是一个未找到的操作,而不是其他什么

我相信这会满足你的要求。您可以继承默认的
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
        }
    }
}
可供替代的
您可以创建一个基本控制器并覆盖
HandleUnknownAction
方法,以获得类似(但更紧密耦合)的结果。

我相信这会满足您的要求。您可以继承默认的
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
        }
    }
}
可供替代的
您可以创建一个基本控制器并覆盖
HandleUnknownAction
方法,以获得类似(但更紧密耦合)的结果。

只是一个旁注:您可能确实希望记录所有这些内容,因为它通常不会发生,但如果发生,则可能表明正在发生攻击。比如有人在你的网站上尝试已知的MVC漏洞或类似的东西。请注意:你可能真的想记录所有这些东西,因为它通常不会发生,但当它发生时,可能表明正在发生攻击。比如有人在你的网站上尝试已知的MVC漏洞或类似的东西。谢谢。我实现了基本控制器的思想,它可以让我控制抛出什么异常,这样我就可以以不同的方式处理这些异常。我可能会在某个时候重新访问action invoker,因为它看起来确实是一个更健壮的解决方案。谢谢。我实现了基本控制器的思想,它可以让我控制抛出什么异常,这样我就可以以不同的方式处理这些异常。我可能会在某个时候重新访问ActionInvoker,因为它看起来确实是一个更健壮的解决方案。