MattSull
MattSull

Reputation: 5564

MVC 4 - LogOff controller action giving 404 not found

I'm just wrapping up a college project, I'm not sure if I've been staring at my computer for too long and am missing something obvious, but when I try to log a user out, I'm getting a 404 not found for the URL /Account/LogOff.

I have a navbar that shows Log in/Log out depending on whether a user is, logged in, or, logged out:

<div class="nav-collapse collapse">
    <ul class="nav pull-right">
        <li class="dropdown" id="dropdown-login-div">
            @if (!Request.IsAuthenticated)
            {
                <a class="dropdown-toggle" href="#" data-toggle="dropdown">Sign In <strong class="caret"></strong></a>
            }
            else
            {
                @Html.ActionLink("Log Off", "LogOff", "Account")
            }
            <div class="dropdown-menu" id="dropdown-login">
                @Html.Partial("~/Views/Account/_LoginPartial.cshtml", new ViewDataDictionary<LetLord.Models.LoginModel>())
            </div>
        </li>
    </ul>
</div>

In my Account controller the default LogOff action that comes with the Internet template:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    WebSecurity.Logout();

    return View("Index");
}

Could someone tell me why this happening - before I throw my laptop against the wall. Cheers.

Upvotes: 17

Views: 16244

Answers (3)

RRay
RRay

Reputation: 1

I ran into this issue on a legacy app. The way that I fixed it was to detect when the supplied return Url was '/Account/LogOff' and act accordingly. From the 'AccountController.cs' file, 'Login' method:

if (returnUrl == "/Account/LogOff")
    {
        return this.RedirectToLocal(null);
    }
    else
    {
        return this.RedirectToLocal(returnUrl);  
    }    

Upvotes: 0

Dan Hunex
Dan Hunex

Reputation: 5318

Since logout modifies server state, I wouldnt remove [HttpPost] and [ValidateAntiForgeryToken] Instead I will replace the link (anchor tag) with the following

@using (Html.BeginForm("Log Out", "Account", FormMethod.Post,
 new { id = "logoutForm" }))
{

    @Html.AntiForgeryToken()
    <a href="javascript:document.getElementById('logoutForm').submit()">Log Out</a>

}

Upvotes: 34

THX-1138
THX-1138

Reputation: 21730

You use a link (<a/> tag) to log off which results in HTTP GET request when user clicks on it, but your action is constrained to serve POST request only (because it is decorated with [HttpPost] attribute).

You either need to put your link into a form and generate POST request, or remove [HttpPost] and [ValidateAntiForgeryToken] (credits to GalacticCowboy) from your action.

Upvotes: 41

Related Questions