为什么Asp.net MVC在具有不同参数时不能区分两个动作?
我试图在我的Asp.net MVC应用程序中有两种不同的帐户注册方法,一种用于一般用户注册,另一种用于注册特定注册令牌的用户。 因此,我的AccountController
有以下方法签名:
public virtual ActionResult Register () {...} public virtual ActionResult Register (Guid registrationToken) {...}
但是,当我转到http://localhost/Account/Register
我得到一个exception,即当前请求在这两个操作之间是不明确的。 我的印象是,如果没有传入registrationToken
GET参数,它将使用无参数的Register
操作,否则它将使用2nd。
这需要特殊的路由配置吗?
使用可为空参数的方法会更容易吗? 这也将自动解决您的问题,因为它不再模棱两可:
public virtual ActionResult Register (Guid? registrationToken) { if(registrationToken.HasValue) { // this is specific user } else { // this is general user } }
对于mvc控制器的默认基类, Controller
使用ActionInvoker来选择要调用的操作。 首先,默认情况下从RouteData [“action”]值中选择操作,然后发生所选操作参数的所有模型绑定和validation。 这就是为什么当调用者看到两个具有相同名称和相同属性的动作进行选择时,它会触发错误,因为它无法区分两者。
但是有内置的方法来管理动作选择逻辑,即使用从ActionMethodSelector类派生的属性。 首先,创建从中派生的类,其中包含用于调用操作的逻辑。 在你的情况下
如果没有传入registrationToken GET参数,它将使用无参数的Register操作,否则它将使用2nd。
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]添加到将用于接受表单提交的任何方法之上通常是有益的。
它也可以解决你的问题。