如何迭代所有 MVC 操作处理程序以确保它们位于 SiteMap 中?

发布于 2024-11-17 00:40:53 字数 595 浏览 4 评论 0原文

我正在编写一个不平凡的“单元测试”(也许更好地称为“UI 测试”?)。在这种情况下,我想我想要一个测试(反思性地?)找到所有适当的操作处理程序,然后验证我们的 SiteMap 是否具有这些操作处理程序的节点。我需要的是确定开发人员何时将页面添加到我们的系统并忘记将其添加到站点地图(这似乎是一个常见问题,我想让它消失,测试应该很容易能够为我们做)。最终,我们希望确保用户可以登陆的任何页面都在我们的 SiteMap 中拥有一个主页,以便它构建适当的面包屑来告诉用户他们在我们系统中的位置(面包屑部分已经非常适合我们,只要该页面位于站点地图中)。我宁愿尝试通过测试来做到这一点,而不是试图强制我们更新一些政策/程序,这是我们必须处理的另一件事。

关于这项工作的一些现有代码有什么建议吗?如果没有,关于最好的方法有什么想法吗?

我正在考虑的一种可能性是反思性地识别任何用AcceptVerbs属性修饰的方法,该属性没有返回类型JsonResult(也许还有其他一些方法)显然不是“网页”,例如 FileResult)。也许通过首先识别继承 System.Web.Mvc.Controller 的类来限制我的搜索。

不过,我很想听到更好的方法。如果大部分内容已经写好并分享以节省我的时间,我会更喜欢。 :-)

I'm working on writing a non-trivial "unit test" (perhaps better called a "UI test"?). In this case, I think I want a test that (reflectively?) finds all appropriate action handlers and then verifies that our SiteMap has a node for those Action Handlers. What I need is to identify when a developer adds a page to our system and forgets to add it to the SiteMap (this seems to be a common problem and I'd like to make it go away, which a test should easily be able to do for us). Ultimately, we want to make sure that any page that a user can land on will have a home in our SiteMap so that it builds the appropriate breadcrumb to tell the user where they are in our system (that breadcrumb part already works perfect for us, as long as the page is in the SiteMap). I would much rather try to do this with a test than try to force some policy/procedure update on us that is yet another thing we have to deal with.

Any tips on some existing code to start from in this endeavor? And if not, any thoughts on the best way to do this?

One possibility that I am considering is to reflectively identify any method that is decorated with the AcceptVerbs attribute which doesn't have a return type of JsonResult (and perhaps a couple others which would clearly not be "web pages" such as FileResult). And perhaps limit my search by first identifying classes which inherit System.Web.Mvc.Controller.

I'd love to hear a better way to do this, though. And would love even more if most of this was already written and shared to save me some time. :-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

莳間冲淡了誓言ζ 2024-11-24 00:40:53

我看到这是mvc应用=>
你的解决方案在于路由(对我来说_)

你知道每个未标记为[nonaction]的选项都在Global.asax中注册
其中包含

  AreaRegistration.RegisterAllAreas();
  RegisterRoutes(RouteTable.Routes);

,在此路由中,您将能够找到所有可访问的方法 => 例如,

这是在基本 mvc 中创建的

操作希望这会有所帮助

I see this is mvc application=>
your solution would lie in routing(for me_)

you know every option which is not marked as [nonaction] is registered in Global.asax
which contains

  AreaRegistration.RegisterAllAreas();
  RegisterRoutes(RouteTable.Routes);

and in this routes you will be able to find all accessible methods =>eg actions

this is created in basic mvc

Hope this will help

如此安好 2024-11-24 00:40:53

这是我的解决方案的重要部分。这对我们来说效果很好。

        var mvcAssembly = typeof (AccountController).Assembly;
        AllControllers = mvcAssembly.GetTypes().Where(type => type.IsSubclassOf(typeof (Controller))).ToList();
        UnfilteredActionHandlers = new List<MethodInfo>();
        foreach (var controller in AllControllers)
        {
            UnfilteredActionHandlers.AddRange(controller.GetMethods()
                                                  .Where(methodInfo =>
                                                         typeof (ActionResult).IsAssignableFrom(methodInfo.ReturnType)
                                                         && !ControllerClassesToIgnore.Contains(methodInfo.ReflectedType)));
        }

我们有一些集合,我们根据我们想要如何使用它们来过滤 UnfilteredActionHandlers 集合:

    internal List<MethodInfo> UnfilteredActionHandlers { get; set; }
    internal List<MethodInfo> ActionHandlersExcludingFilteredReturnTypes { get; set; }
    internal List<MethodInfo> ActionHandlersFilteredByAttributes { get; set; }
    internal List<MethodInfo> ActionHandlersFilteredByBoth { get; set; }


    internal static List<Type> ReturnTypesToIgnore { get; set; }
    internal static List<Type> RequiredAttributes { get; set; }
    internal static List<Type> ControllerClassesToIgnore { get; set; }

Here is the important part of my solution. This works well for us.

        var mvcAssembly = typeof (AccountController).Assembly;
        AllControllers = mvcAssembly.GetTypes().Where(type => type.IsSubclassOf(typeof (Controller))).ToList();
        UnfilteredActionHandlers = new List<MethodInfo>();
        foreach (var controller in AllControllers)
        {
            UnfilteredActionHandlers.AddRange(controller.GetMethods()
                                                  .Where(methodInfo =>
                                                         typeof (ActionResult).IsAssignableFrom(methodInfo.ReturnType)
                                                         && !ControllerClassesToIgnore.Contains(methodInfo.ReflectedType)));
        }

We have a few collections that we filter the UnfilteredActionHandlers collection by depending on how we want to use them:

    internal List<MethodInfo> UnfilteredActionHandlers { get; set; }
    internal List<MethodInfo> ActionHandlersExcludingFilteredReturnTypes { get; set; }
    internal List<MethodInfo> ActionHandlersFilteredByAttributes { get; set; }
    internal List<MethodInfo> ActionHandlersFilteredByBoth { get; set; }


    internal static List<Type> ReturnTypesToIgnore { get; set; }
    internal static List<Type> RequiredAttributes { get; set; }
    internal static List<Type> ControllerClassesToIgnore { get; set; }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文