具有相同动作名称

具有相同动作名称

问题描述:

多个动作我有这样具有相同动作名称

public ActionResult Verify(String email, String name){ 
     ViewBag.email = email; 
     ViewBag.name = name; 
     return View(); 
} 

[HttpGet] 
public ActionResult Verify(String uId){ 
     User user = TippNett.Core.User.Get(uId); 
     user.Active = true; 
     user.Save(); 
     Auth.Authenticate(user, false); 
     return RedirectToAction("Index", "Home"); 
} 

在我的控制器的多个动作的第一个动作是,当用户注册,以显示他的注册消息,请验证电子邮件和我打电话像此

return RedirectToAction("Verify", "Account", new { email = email, name = user.FirstName}); 

当用户单击验证链接时会调用第二个操作。 问题在于下面的函数总是被调用。即使我通过电子邮件和名称作为参数。

任何人都可以解释为什么会发生这种情况,并可能解决这个问题?

+0

解决方法:使用不同的名称! – DavidG 2015-02-09 13:21:11

+0

更好看看这个http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx/ – 2015-02-09 13:21:31

您可以使用:

[ActionName("MyOverloadedName")] 

method overloading based on attribute:

[RequireRequestValue("someInt")] 
public ActionResult MyMethod(int someInt) { /* ... */ } 

[RequireRequestValue("someString")] 
public ActionResult MyMethod(string someString) { /* ... */ } 

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; } 
} 

但是,你必须使用一个不同的动作名称相同的HTTP方法使用不同的http方法时只能使用相同的方法。 像:

[HttpPost] 
public ActionResult Verify(String email, String name){ 
     } 

[HttpGet] 
public ActionResult Verify(String uId){ 
     User user = TippNett.Core.User.Get(uId); 
     user.Active = true; 
     user.Save(); 
     Auth.Authenticate(user, false); 
     return RedirectToAction("Index", "Home"); 
} 
+1

感谢您的解释。 – mohsinali1317 2015-02-09 13:34:30

您应该使用HttpPost属性看到:

HttpPost vs HttpGet attributes in MVC: Why use HttpPost?

以获取更多信息。

最近我拿了以进一步缩小@图莎尔的伟大RequireRequestValueAttribute让它支持更多的场景,比如多参数的支持和不同类型的比赛,将触发它的机会:所有给定的参数,其中任何一个,甚至没有。

我打电话给新版本RequiredParameterAttribute,我在所有最终使用的MVC项目中都使用它。

下面是完整的源代码:

/// <summary> 
/// Flags an Action Method valid for any incoming request only if all, any or none of the given HTTP parameter(s) are set, 
/// enabling the use of multiple Action Methods with the same name (and different signatures) within the same MVC Controller. 
/// </summary> 
public class RequireParameterAttribute : ActionMethodSelectorAttribute 
{ 
    public RequireParameterAttribute(string parameterName) : this(new[] { parameterName }) 
    { 
    } 

    public RequireParameterAttribute(params string[] parameterNames) 
    { 
     ParameterNames = parameterNames; 
     IncludeGET = true; 
     IncludePOST = true; 
     IncludeCookies = false; 
     Mode = MatchMode.All; 
    } 

    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) 
    { 
     switch (Mode) 
     { 
      case MatchMode.All: 
      default: 
       return (
        (IncludeGET && ParameterNames.All(p => controllerContext.HttpContext.Request.QueryString.AllKeys.Contains(p))) 
        || (IncludePOST && ParameterNames.All(p => controllerContext.HttpContext.Request.Form.AllKeys.Contains(p))) 
        || (IncludeCookies && ParameterNames.All(p => controllerContext.HttpContext.Request.Cookies.AllKeys.Contains(p))) 
        ); 
      case MatchMode.Any: 
       return (
        (IncludeGET && ParameterNames.Any(p => controllerContext.HttpContext.Request.QueryString.AllKeys.Contains(p))) 
        || (IncludePOST && ParameterNames.Any(p => controllerContext.HttpContext.Request.Form.AllKeys.Contains(p))) 
        || (IncludeCookies && ParameterNames.Any(p => controllerContext.HttpContext.Request.Cookies.AllKeys.Contains(p))) 
        ); 
      case MatchMode.None: 
       return (
        (!IncludeGET || !ParameterNames.Any(p => controllerContext.HttpContext.Request.QueryString.AllKeys.Contains(p))) 
        && (!IncludePOST || !ParameterNames.Any(p => controllerContext.HttpContext.Request.Form.AllKeys.Contains(p))) 
        && (!IncludeCookies || !ParameterNames.Any(p => controllerContext.HttpContext.Request.Cookies.AllKeys.Contains(p))) 
        ); 
     } 
    } 

    public string[] ParameterNames { get; private set; } 

    /// <summary> 
    /// Set it to TRUE to include GET (QueryStirng) parameters, FALSE to exclude them: 
    /// default is TRUE. 
    /// </summary> 
    public bool IncludeGET { get; set; } 

    /// <summary> 
    /// Set it to TRUE to include POST (Form) parameters, FALSE to exclude them: 
    /// default is TRUE. 
    /// </summary> 
    public bool IncludePOST { get; set; } 

    /// <summary> 
    /// Set it to TRUE to include parameters from Cookies, FALSE to exclude them: 
    /// default is FALSE. 
    /// </summary> 
    public bool IncludeCookies { get; set; } 

    /// <summary> 
    /// Use MatchMode.All to invalidate the method unless all the given parameters are set (default). 
    /// Use MatchMode.Any to invalidate the method unless any of the given parameters is set. 
    /// Use MatchMode.None to invalidate the method unless none of the given parameters is set. 
    /// </summary> 
    public MatchMode Mode { get; set; } 

    public enum MatchMode : int 
    { 
     All, 
     Any, 
     None 
    } 
} 

我保留了“老”签名,以便它可以用来就像以前的分期付款。

有关更多信息和一些实施示例,您还可以阅读this post