Eric Yeoman
Eric Yeoman

Reputation: 1036

MVC - URL.Action gives Resource not found error

I've got the following in my _Layout.cshtml file:

<a href="@Url.Action("LogOff", "Account")"><span class="fa fa-files-o"></span> <span class="xn-text">NEW Log Out</span></a>

However, when I click on the link I get 'The resource cannot be found' error message.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

Requested URL: /Account/LogOff

The Account controller has not been edited or moved, same state as the default MVC 5 template.

The HTML rendered is:

<a href="/Account/LogOff"><span class="fa fa-files-o"></span> <span class="xn-text">NEW Log Out</span></a>

EDIT: I am able to login from a screen which does not use the _layout screen, so the account controller can be found in other parts of the application. The login then goes to the Home/Index action and returns the Index View with the layout.

Also, the Account Controller has not been edited in any way, all methods, declarations, everything is left untouched from the original default template. The controller is being found in another part of the code, as the login function works.

Upvotes: 0

Views: 3774

Answers (2)

Damian
Damian

Reputation: 606

Based on your comment:

Oh, you need a [HttpPost] at least on that. Plus some code to actually log out, not just redirecting to the homepage might be useful too

Your problem sounds like the code within your server logic is annotated with an [HttpPost], if it is then your HREF is looking for a GET Action/ViewResult which clearly doesn't exist.

You can fix this in one of three ways. Remove the [HttpPost] from your server logic and it should work (definitely not best practice), or you can re-adjust your view to do one of the following:

Solution One - How the Internet Application Template Originally Looked

@using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { 
            @class = "no-margin", id = "logoutForm"}))
{
    @Html.AntiForgeryToken()
}

<a href="javascript:document.getElementById('logoutForm').submit()">
    <span class="fa fa-files-o"></span> <span class="xn-text">NEW Log Out</span>
</a>

Solution Two - A slightly different approach to the one above

@using (Html.BeginForm("LogOff", "Account", FormMethod.Post, null}))
{
    @Html.AntiForgeryToken()

    <button type="submit">
        <span class="fa fa-files-o"></span> <span class="xn-text">NEW Log Out</span>
    </button>
}

In your LogOff action, you then just need to do the following:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    WebUserSecurity.Logout();
    Session.Abandon();

    return RedirectToAction("Login", "Account");
}

Upvotes: 1

alexo
alexo

Reputation: 934

You need to have a Controller named AccountController and a method on it named LogOff in order for this to work.

The structure should be something like this:

[Authorize]
public class AccountController : Controller
{
    public AccountController()
    {
    }

    public ActionResult LogOff()
    {
        // logout code here
        return RedirectToAction("Index", "Home"); // this you can change in whatever you like
    }
}

Upvotes: 2

Related Questions