ASP.Net MVC控制器命名空间数组

9
我注意到MapRoute扩展包含一个重载,它接受一个名为“namespaces”的字符串数组参数。我阅读了谷歌上对此的解释,据说这是为了帮助框架在其他位置查找控制器。
我进行了一些尝试,尝试将控制器放在奇怪的位置。我把一个控制器放在Scripts文件夹中;我甚至在一个单独的程序集中构建了一个具有不同根命名空间的控制器。
如果没有将任何内容放入命名空间参数中,一切都正常工作。即使我只在命名空间参数中放置其中一个命名空间,它仍然可以找到所有我的控制器。我以为它会使用该数组来消除同名控制器之间的歧义,但这也没有发生。MyProj.Controllers中的HomeController和SomeOtherName.Stuff中的HomeController仍然会冲突。
所以我的问题是,这个参数是否已被弃用?还是它仍然以某种我尚未发现的方式被使用?
2个回答

5

好的,经过进一步测试,我发现它不完全是一个过滤器,但也有点像。尽管你的答案部分正确,但我还是给了你“答案”信用。

所以,它确实像我想象的那样起到了消除歧义的作用。基本上,逻辑流程如下:

  • 在缓存中查找与命名空间数组中匹配的命名空间
    • 如果找到了,就查找正确名称的控制器
    • -- 如果找到了,就返回它
    • -- 如果没有找到,就返回通常情况下会查找的其他地方
  • 如果没有找到,就到处搜索

因此,简而言之,我的想法是命名空间数组将用于消除歧义。我第一次测试失败的原因是它只进行了完全匹配,而我犯了一个错误,使用了程序集的根n/s(换句话说,使用了MyRoot而不是MyRoot.Controllers)。

这个命名空间的功能允许在两个不同的命名空间中具有一个HomeController,并根据URL或参数的不同进行不同的匹配。


4
不,该值并未被弃用。它在DefaultControllerFactory.cs中使用。请注意,如果提供该值,则会完全替换标准名称空间的搜索。当未提供参数时,搜索的名称空间由以下确定:
HashSet<string> nsDefaults = new HashSet<string>(ControllerBuilder.DefaultNamespaces, StringComparer.OrdinalIgnoreCase);

当提供参数时,您提供的列表将替换此值。
在任何情况下,默认控制器工厂都会调用:
GetControllerTypeWithinNamespaces(controllerName, nsDefaults);

...与提供的列表或默认列表一起,从中可以清楚地看出该值是被支持的。

当你查看源代码和ControllerTypeCache时,你可以看到命名空间值的真实目的:它不会使控制器工厂找到本来不会搜索的位置;相反,它是一个过滤器。换句话说,它防止默认控制器工厂查找它本来会搜索的命名空间下的控制器。


我认识到这是它应该工作的方式,并且我在DefaultControllerFactory中找到了您描述的相同位置,但是当我运行上述描述的测试时,它并不是这样工作的。 我提供了不存在的命名空间,但工厂仍然找到了我的控制器。 - Paul
ControllerTypeCache中的代码看起来对我来说确实是这样工作的。您可以通过使用源代码进行构建来调试它。也许有些东西您没有提供? - Craig Stuntz
我同意看起来是这样的,并且在测试之前我使用源代码进行了构建;我将尝试使用一些不同的参数再次尝试。 - Paul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接