为什么可以';当两个操作具有不同的参数时,t Asp.net MVC会区分它们

本文关键字:参数 Asp net 会区 MVC 操作 两个 为什么 | 更新日期: 2023-09-27 18:00:17

我正在尝试在我的Asp.net MVC应用程序中使用两种不同的帐户注册方法,一种用于普通用户注册,另一种用于使用特定注册令牌注册的用户。因此,我的AccountController中有以下方法签名:

public virtual ActionResult Register () {...}
public virtual ActionResult Register (Guid registrationToken) {...}

然而,当我转到http://localhost/Account/Register时,我得到一个异常,即当前请求在这两个操作之间是不明确的。我的印象是,如果没有传入registrationToken GET参数,它将使用无参数的Register操作,否则它将使用第二个。

这需要特殊的路线配置吗?

为什么可以';当两个操作具有不同的参数时,t Asp.net MVC会区分它们

有一个可以为null的参数的方法会更容易吗?这也将自动解决您的问题,因为它将不再是模棱两可的:

public virtual ActionResult Register (Guid? registrationToken)
{
    if(registrationToken.HasValue)
    {
         // this is specific user
    }         
    else
    {
         // this is general user
    }
}

mvc控制器的默认基类,Controller使用ActionInvoker来选择要调用的操作。首先,在默认情况下,从RouteData["action"]值中选择操作,然后对所选操作的参数进行所有模型绑定和验证。这就是为什么当调用程序看到两个具有相同名称和相同属性的操作用于选择时,它会引发错误,因为它无法区分两者。

但是有一种内置的方法可以管理操作选择逻辑,即使用ActionMethodSelector类派生的属性。首先创建派生自它的类,该类包含用于调用操作的逻辑。在您的情况下

它将使用无参数如果没有,请注册操作registrationToken GET参数已传递在中,否则将使用第2个。

 public class RegistrationActionTokenAttribute : ActionMethodSelectorAttribute
    {
        public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
        {
            if (controllerContext.HttpContext.Request.QueryString.AllKeys.Contains("registrationToken"))
            {
                return true;
            }
            return false;
        }
    }

我实现了演示逻辑,即如果querystring包含参数"registrationToken",则第二个操作应标记为可供选择的有效操作。剩下的唯一一件事是用这个属性装饰你的第二种方法

[RegistrationActionToken]    
public virtual ActionResult Register (Guid registrationToken) {...}

错误已经消失了。此外,控制器现在根据查询字符串参数

选择正确的操作

第二个方法需要Post吗?在将用于接受表单提交的任何方法之上添加[HttpPost]通常是有益的。

它也可能解决你的问题。