我刚才意识到我多年来一直在使用的东西应该不起作用!考虑以下操作的多态性:
public ActionResult MyAction() { ... }
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyAction(String input) { ... }
很明显,当我们使用 GET 时,只有第一个仍然是有效的候选者,因为该属性会过滤掉后者。因此,它是明确的,每个人都很高兴。但是,如果我们使用 POST
跳转到代码中会怎么样?乍一看,人们很容易发现,由于第一种方法是更一般的行动,后者更适合在这种特殊情况下使用“以涵盖特价” , 可以这么说。但那是人类的逻辑。我怀疑服务器的原因是这样的。
我已经查看了我可以在项目中找到的路线和其他文件,但据我所知,有一些黑魔法涉及。 :)
所以我的问题是:框架如何知道要选择什么?
需要跟进的问题是MVC版本是否有所不同。
答案 0 :(得分:3)
我建议阅读Phil Haack的How a Method Becomes An Action,它应该回答你的问题。引用一些重要部分:
ActionSelectionAttribute
一旦我们识别出与当前操作名称匹配的Controller类的所有方法,我们需要通过查看应用于列表中方法的ActionSelectionAttribute的所有实例来进一步缩小列表。
此属性是属性的抽象基类,可以对操作方法可以响应的请求进行细粒度控制。此方法的API非常简单,只包含一个方法。
public abstract class ActionSelectionAttribute : Attribute
{
public abstract bool IsValidForRequest(ControllerContext controllerContext,
MethodInfo methodInfo);
}
然后再往下走一点:
最后,我们应该在列表中留下一个方法,然后调用者调用它。如果多个方法可以处理当前请求,则调用者抛出指示问题的异常。如果没有方法可以处理请求,则调用者在控制器上调用HandleUnknownAction()。
ASP.NET MVC框架包含此基本属性的一个实现,即AcceptVerbsAttribute。
本文接着解释了这个过程如何与AcceptVerbsAttribute
一起使用,展示了一个与你的相似的例子。
答案 1 :(得分:1)
框架的确如你所做的那样:选择后一种行为是因为它被认为更具体。我没有检查过每个版本,但自从引入HttpPostAttribute
以来,我认为这种行为没有改变。
但是,我已经多次下载了ASP.NET MVC源代码,我可以看到实现确实有所改变。有一段时间,RunSelectionFilters
ActionMethodSelector
方法中源代码的相关部分如下所示:
// if a matching action method had a selection attribute, consider it more
// specific than a matching action method without a selection attribute
return (matchesWithSelectionAttributes.Count > 0)
? matchesWithSelectionAttributes
: matchesWithoutSelectionAttributes;
但这不是当前的实现。在the source code on codeplex right now中,实现有点复杂,但行为是相同的,参见RunSelectionFilters(...)
的{{1}}内的评论:
ActionMethodSelectorBase.cs