ASP.NET MVC操作方法的歧义调用

4

有人能解释一下为什么对以下操作进行POST调用是不明确的吗?它们有不同的参数集合?

[RequireRequestValueAttribute("setID")]
public ActionResult Add(int setID){}

[HttpPost]
public ActionResult Add(TypeModel model, int? queueID) {}

当使用RequireRequestValueAttribute属性时才会出现此问题,我正在使用它是因为我想为不同参数集添加另一个Get调用方法。

以下是我正在使用的实现,在另一个stackoverflow问题中找到:

public class RequireRequestValueAttribute : ActionMethodSelectorAttribute
{
    public RequireRequestValueAttribute(string valueName)
    {
        ValueName = valueName;
    }
    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
        return (controllerContext.HttpContext.Request[ValueName] != null);
    }
    public string ValueName { get; private set; }
} 
3个回答

6

C#中禁止使用相同名称和参数类型的两个方法,这与ASP.NET MVC无关。您应该重命名其中一个Add操作,可以通过GET调用。

您不能有两个具有相同名称且可以使用相同动词(在您的情况下为GET)调用的操作名称。您需要重命名其中一个或使用另一个HTTP动词,就像您在POST操作中所做的那样。


更新:

您可以尝试在自定义操作选择器属性中引入HTTP动词:

public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
    return controllerContext.HttpContext.Request[ValueName] != null &&
           controllerContext.HttpContext.Request.HttpMethod == "GET";
}

但是说实话,我不会使用自定义操作选择器来验证请求参数是否存在。路由约束或数据注释似乎更适合这个任务。


抱歉,打错字了,第二个方法的参数是非空整数。 - lahsrah
@sylon,请看我的更新:你不能有两个具有相同名称且可以使用相同动词调用的操作。 - Darin Dimitrov
我不明白为什么如果我删除方法2,帖子就可以正常工作并进入方法3。但是如果我删除方法1,则发布会失败并出现模糊调用错误。所有三种方法都可以发布,对吧?那么为什么问题只出现在第二个和第三个方法上? - lahsrah
谢谢您的建议,我会研究一下。顺便说一下,[HttpGet]属性比您建议的添加额外检查到我的属性更好。 - lahsrah
请查看我的原始帖子以了解我的真正问题。但是感谢您提供有关路由约束或数据注释的提示。我不知道这些是什么,但会研究一下。 - lahsrah
显示剩余2条评论

3
做自己一个很大的好处。下载ASP.NET MVC的源代码。(实际上,每当您有访问源代码的机会时,都应该这样做。)设置它以进行调试并逐步执行您遇到问题的部分。我无法告诉您有多少次这已经为我解决了这样的问题。您将获得比您否则拥有的更好的理解,而在某些情况下,您可能会发现真正令人惊讶的事情。过去我曾在这里提出问题,得到了“可行”的解决方案,只是发现有一种更简单、更优雅的方法来解决问题。

0

好的,回答我自己的问题,这是我的愚蠢!

我的get方法有setID参数,因为它在URL中,当然这也会在post中,因此RequireRequestValueAttribute对于两种方法的IsValidForRequest都返回TRUE。我通过向Get方法添加[HttpGet]属性来解决这个问题,这样就永远不会将东西发布到它上面。


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