MVC Ambiguous Action for Login

1.3k views Asked by At

I've got an ASP.NET MVC4 website (using vs2012) that allows users to login by clicking the "login" link. I'm getting the infamous error:

The current request for action 'Login' on controller type 'AccountController' is ambiguous between the following action methods: System.Web.Mvc.ActionResult Login() on type MyProject.Controllers.AccountController System.Web.Mvc.ActionResult Login(MyProject.Clients) on type MyProject.Controllers.AccountController

I've checked a bunch of links on here, including:

Resolving ambiguity Ambiguous action method call, for some reason ASP.NET MVC 3

and a few more outside of SO. I've made sure I have the methods decorated correctly but still can't find the reason this is happening.

Here's my code for the "Login" link:

    <ul class="topnav navRight">
        @if (!User.Identity.IsAuthenticated)
        {
            <li><a href="@Url.Action("Login", "Account")" id="ViewLogin">LOGIN</a></li>
        }
        else
        {
            <li><a href="@Url.Action("Index", "ClientStats")">STATS</a></li>
            <li><a href="@Url.Action("LogOut", "Account")">LOGOUT</a></li>
        }
    </ul>

and my Controller:

[Authorize]
public class AccountController : CustomController
{
    //
    // GET: /Account/Logout
    public ActionResult LogOut()
    {
        WebSecurity.Logout();
        return RedirectToAction("Index", "Home");
    }

[AllowAnonymous]
public virtual ActionResult Login()
{
    return View();
}

[HttpPost]
[AllowAnonymous]
public virtual ActionResult Login(Clients model)
{
    if (ModelState.IsValid)
    {
        Security security = new Security();

        if (WebSecurity.Login(model.Username, model.Password))
        {
            using (MyProjectContext db = new MyProjectContext())
            {
                int userID = WebSecurity.GetUserId(model.Username);
                Data.User user = db.Users.Find(userID);

                if (user != null)
                    if (user.Active)
                    {
                        if (User.IsInRole("Administrator"))
                            return RedirectToAction("Admin", "ClientStats");
                        else
                            return RedirectToAction("Index", "ClientStats");
                    }
            }
        }
    }

    ModelState.AddModelError("", "Invalid Username or Password.");

    return View(model);
}

}

The CustomerController has nothing special in it but here it is anyways:

    public class CustomController : Controller
{
    public enum PageNames
    {
        Home,
        Services,
        Testimonials,
        Video,
        Photo,
        FAQ,
        About,
        Contact,
        Events,
        Profile
    }

    public int UserId
    {
        get { return Convert.ToInt32(Session["UserId"]); }
        set { Session["UserId"] = value; }
    }

    public static string GetPageTitle(PageNames pageName)
    {
        string pageTitle = "Welcome to My Website!";

        switch (pageName)
        {
            case PageNames.Services:
                pageTitle = "- Services";
                break;

            case PageNames.Testimonials:
                pageTitle = "- Testimonials";
                break;

            case PageNames.Video:
                pageTitle = "- Videos";
                break;

            case PageNames.Photo:
                pageTitle = "- Photos";
                break;

            case PageNames.FAQ:
                pageTitle = "- Frequently Asked Questions";
                break;

            case PageNames.Contact:
                pageTitle = "- Contact Us";
                break;

            case PageNames.Events:
                pageTitle = "- Calnedar of Events";
                break;

            case PageNames.Profile:
                pageTitle = "- Profile";
                break;
        }

        return pageTitle;
    }

    public static Data.User ClientInfo { get; set; }
}

And here's the routing information...I've tried to uncomment the one route (and changed it's name) but I still get the same error:

    public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}",
            defaults: new { controller = "Home", action = "Index" }
        );

        //routes.MapRoute(
        //    name: "Default",
        //    url: "{controller}/{action}/{id}",
        //    defaults: new { controller = "Account", action = "Login", id = UrlParameter.Optional }
        //);

        routes.MapRoute(
            name: "id",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

Any help/guidance is greatly appreciated!

UPDATE I've tried the suggestions of commenting out the routing values and adding [HttpGet] to the Login method but it still throws the same error. I do recall this working at one time so I don't know what has changed lately to make it do this all of a sudden. Could it be something in the Web.Config?

2

There are 2 answers

3
JC Lizard On

MVC doesn't support method overloading based solely on signature take [AllowAnonymous] out

add a [HttpGet] to the get actionresult and the problem should be solved

[HttpGet]
public virtual ActionResult Login()
{
    return View();
}
0
Ben Lynch On

I had this issue, and it turned out to be the fact that I had opened System.Web.Http namespace, which also defines [HttpGet]/[HttpPost] attributes. These attributes were therefore being used in preference to those in System.Web.Mvc, the latter being the ones responsible to allowing method overloading in controllers, based on Http verbs. Commenting out

 open System.Web.Http 

resolved the problem, allowing Mvc to choose the correct ([HttGet]) overload.