reflection - ASP.NET MVC - 使用反射来查找 Controller 是否存在

标签 reflection asp.net-mvc-2 routing constraints

我花了很长时间弄清楚如何正确实现我的 404 重定向。

如果我使用以下

<HandleError()> _
Public Class BaseController : Inherits System.Web.Mvc.Controller
''# do stuff
End Class

然后页面上任何未处理的错误都会加载“错误” View ,效果很好。 http://example.com/user/999 (其中 999 是无效的用户 ID)会在保持原始 URL 的同时抛出错误(这就是我想要的)

然而。如果有人输入 http://example.com/asdfjkl进入 url(其中 asdfjkl 是无效的 Controller ),然后 IIS 抛出通用 404 页面。 (这是 不是 我想要的)。我需要的是应用上述相同的内容。保留原始 URL,并加载“NotFound” Controller 。

我正在像这样注册我的路线
Shared Sub RegisterRoutes(ByVal routes As RouteCollection)
    routes.RouteExistingFiles = False
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
    routes.IgnoreRoute("Assets/{*pathInfo}")
    routes.IgnoreRoute("{*robotstxt}", New With {.robotstxt = "(.*/)?robots.txt(/.*)?"})

    routes.AddCombresRoute("Combres")

    routes.MapRoute("Start", "", New With {.controller = "Events", .action = "Index"})

    ''# MapRoute allows for a dynamic UserDetails ID
    routes.MapRouteLowercase("UserProfile", "Users/{id}/{slug}", _
                             New With {.controller = "Users", .action = "Details", .slug = UrlParameter.Optional}, _
                             New With {.id = "\d+"} _
    )


    ''# Default Catch All MapRoute
    routes.MapRouteLowercase("Default", "{controller}/{action}/{id}/{slug}", _
                             New With {.controller = "Events", .action = "Index", .id = UrlParameter.Optional, .slug = UrlParameter.Optional}, _
                             New With {.controller = New ControllerExistsConstraint})

    ''# Catch everything else cuz they're 404 errors
    routes.MapRoute("CatchAll", "{*catchall}", _
                    New With {.Controller = "Error", .Action = "NotFound"})

End Sub

请注意 ControllerExistsConstraint ?我需要做的是使用反射来发现 Controller 是否存在。

有人可以帮我填空吗?
Public Class ControllerExistsConstraint : Implements IRouteConstraint

    Public Sub New()
    End Sub

    Public Function Match(ByVal httpContext As System.Web.HttpContextBase, ByVal route As System.Web.Routing.Route, ByVal parameterName As String, ByVal values As System.Web.Routing.RouteValueDictionary, ByVal routeDirection As System.Web.Routing.RouteDirection) As Boolean Implements System.Web.Routing.IRouteConstraint.Match


        ''# Bah, I can't figure out how to find if the controller exists


End Class

我还想知道这对性能的影响……反射的性能有多大?如果太多,有没有更好的方法?

最佳答案

我有一个 C# 解决方案,希望对您有所帮助。我抄袭了其中的一些代码,但在我的一生中,我找不到它从哪里得到的。如果有人知道,请告诉我,以便我可以将其添加到我的评论中。

此解决方案不使用反射,但会查看所有应用程序错误(异常)并检查是否为 404 错误。如果是,那么它只是将当前请求路由到不同的 Controller 。虽然我不是任何方面的专家,但我认为这个解决方案可能比反射更快。无论如何,这是解决方案,它会进入您的 Global.asax.cs,

    protected void Application_Error(object sender, EventArgs e)
    {
        Exception exception = Server.GetLastError();

        // A good location for any error logging, otherwise, do it inside of the error controller.

        Response.Clear();
        HttpException httpException = exception as HttpException;
        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "YourErrorController");

        if (httpException != null)
        {
            if (httpException.GetHttpCode() == 404)
            {
                routeData.Values.Add("action", "YourErrorAction");

                // We can pass the exception to the Action as well, something like
                // routeData.Values.Add("error", exception);

                // Clear the error, otherwise, we will always get the default error page.
                Server.ClearError();

                // Call the controller with the route
                IController errorController = new ApplicationName.Controllers.YourErrorController();
                errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
            }
        }
    }

所以 Controller 将是,
public class YourErrorController : Controller
{
    public ActionResult YourErrorAction()
    {
        return View();
    }
}

关于reflection - ASP.NET MVC - 使用反射来查找 Controller 是否存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3432089/

相关文章:

generics - 如何使用 Scala 的 Manifest 类在运行时实例化已删除的类?

http - 如何覆盖 GoLang 中的组合结构方法

c# View 调用 Angular 组件中断,但直接调用 Angular 工作正常

ruby-on-rails - Perl 中的 Rails 或 Django 样式路由

asp.net-mvc - 我可以从操作过滤器获取操作的返回类型吗?

java - 使用反射调用方法时 int 和 Integer 参数的区别

Java 反射等于问题

asp.net - 为什么 Asp.net mvc 应用程序不能在 Asp.Net Classic 应用程序池上运行?

asp.net-mvc - 使用默认模型 Binder 映射集合的约定是什么?

unit-testing - 未注册在 httpModules 中测试 nhibernate CaSTLe Windsor 映射