以符号方式指定 ASP.NET MVC 3 路由
我真的很喜欢 ASP.NET MVC 3 框架。或者至少,它肯定比尝试欺骗 ASP.NET 3.5 或 4.0 好得多。然而,我只是对某些事情感到非常困惑。他们为什么选择用字符串指定路由?
IOW,我被告知要像这样指定我的路由(例如):
... new { controller = "Products", action = "List", id = UrlParameter.Optional }
该路由与 ProductsController.List() 方法匹配。假设我正处于重构状态,并且想将 ProductsController 重命名为 InventoryController。使用我选择的重命名工具后,我打开 Global.aspx 并浏览所有路线,并将所有这些愚蠢的字符串更改为“Inventory”。您可能会回答说我可以查找并替换...但是来吧!我觉得这是最后一代的答案。
当我更好地理解我的领域时,我喜欢重构我的代码。我不想使用愚蠢(我说愚蠢是因为它们对编译器没有意义)字符串来引用与最终存储在符号表中的类型和方法名称完全对应的符号/语义代码构造。重点是什么?为什么要为类型烦恼呢?让我们回到使用关联数组和字典来表示我们的域模型来编写脚本......在我看来,当我们将强类型与字符串引用混合时,强类型的好处会大大减弱。
但说实话,一个选择就是反思。这会对性能造成影响吗?我想 MVC 框架必须使用“Products”字符串上的反射来获取我的 ProductsController,所以...而且,您还必须删除类型名称的“Controller”部分,如下所示:
= typeof(ProductsController).Name.Replace("Controller", string.Empty)
我可以使用以下内容辅助函数使其变得有点干燥:
public string GetControllerName(Type controller)
{
return controller.Name.Replace("Controller", string.Empty);
}
基准测试是有序的,如果这是避免这些字符串的唯一方法......不过,这很愚蠢。我在类型上使用反射来获取字符串,MVC 将使用该字符串与反射结合使用来获取我最初拥有的类型。
是否有某种原因不采取下一步(逻辑?)并使控制器和操作属性直接期望类型和委托?这样不是更干净、更清晰吗?据我所知,MVC 的一个基本方面是约定优于配置,但使用这些字符串进行路由对我来说似乎是一种偷偷摸摸的配置形式。
还有其他办法解决这个问题吗?我对 MVC 还是个新手。我读到我们可以替换这些路由组件。有谁知道是否可以做我所说的事情?如果不可能的话,那么……只有我一个人在这里吗?我错过了什么吗?为什么这些路由必须由哑字符串设置的最重要原因是什么?如果不是,这可能是值得游说的事情吗?
只有我一个人讨厌这样使用字符串吗?我仍然认为 C# 需要类似于 Ruby 符号和 Lisp 关键字的东西,我们的重构工具可以利用它们。有点像“字符串枚举”,其中枚举值名称同时也是值。
我知道这个问题的部分内容是主观的,但我也在寻找关于是否可以直接使用类型和委托来指定这些路由配置的客观答案。
谢谢你, 杰罗迈耶斯
I really like the ASP.NET MVC 3 framework. Or at least, it sure is incomparably better than trying to fool with ASP.NET 3.5 or 4.0. However, I am just really confused about something. Why did they choose to specify routes with strings?
IOW, I am told to specify my routes like this (for instance):
... new { controller = "Products", action = "List", id = UrlParameter.Optional }
This route matches a ProductsController.List() method. Let's say I'm in a refactoring mood and I want to rename my ProductsController to InventoryController. After using my renaming tool of choice, I have open up Global.aspx and go through all my routes and change all these stupid strings to "Inventory". You might respond that I can do a find and replace... but come on! I feel like that is such a last-generation answer.
I love refactoring my code as I come to understand my domain better. I don't want to use stupid (I say stupid because they have no significance to the compiler) strings to refer to symbolic/semantic code constructs that correspond exactly to type and method names that are ultimately stored in a symbol table. What is the point? Why bother with types at all? Let's just go back to writing scripts using associative arrays and dictionaries to represent our domain model... it seems to me that the benefit of strong typing is greatly lessened when we mix it with string references.
Seriously, though, an option would be reflection. Would there be a performance hit for this? I suppose the MVC framework must be using reflection on that "Products" string to get my ProductsController, so... But also, you would have to remove the "Controller" portion of the type name, as follows:
= typeof(ProductsController).Name.Replace("Controller", string.Empty)
I could use the following helper function to make it a little DRYer:
public string GetControllerName(Type controller)
{
return controller.Name.Replace("Controller", string.Empty);
}
Benchmarking is in order, if this is the only way to avoid those strings... Still, this is stupid. I'm using reflection on a type to get a string that MVC is going to use in conjunction with reflection to get the type I originally had in the first place.
Is there some reason not take the next (logical?) step and have the controller and action properties expect Types and Delegates directly? Wouldn't this simply be cleaner and clearer? So far as I understand, a fundamental aspect of MVC is convention over configuration, but routing with those strings just seems to be a furtive form of configuration to me.
Is there another way around this? I am still new to MVC. I've read that we can replace these routing components. Does anyone know if it is possible to do what I'm talking about? And if it's not possible, well... am I alone here? Am I missing something? Some overriding reason why it is essential that these routes be set by dumb strings? If not, could this maybe be something to lobby for?
Am I alone in hating it when strings are used in this way? I still think C# needs something akin to Ruby's symbols and Lisp's keywords that our refactoring tools could take advantage of. Sort of like "string enumerations" where the enumeration value name is at the same time the value.
I understand that parts of this question are subjective, but I am also looking for the objective answer on whether it is possible to directly use types and delegates to specify these routing configurations.
Thank you,
Jeromeyers
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
就我个人而言,我从来没有遇到过路由定义方式的问题,因为我总是对它们进行单元测试 。因此,如果我有重构的心情,我的单元测试总是保证路由会按照我想要的方式运行。
当然,如果您仍然对 ASP.NET MVC 团队设计框架的方式不满意(请毫不犹豫地开票并投票支持未来版本的改进),您可以随时编写自定义路由:
然后而不是:
您可以:
现在您可以根据需要重命名控制器和操作。
Personally I never had problems with the way routes are defined because I always unit test them. So if I am in a refactoring mood, my unit tests always guarantee me that the routes will behave as I want.
Of course if you are still not satisfied with the way the ASP.NET MVC team designed the framework (don't hesitate to open a ticket and vote for improvement in future versions) you could always write a custom route:
and then instead of:
you could:
Now you can rename your controllers and actions as much as you like.