I'm using Adam Freeman's book called "Pro ASP.NET MVC", and trying to implement the chapter 12, a simple web application of Authentication.
This web application uses:
Login.cshtml
(~/Account/Login
);AccountController.cs
Web.config
You can see Login.cshtml
here:
@model SportsStore.WebUI.Models.LoginViewModel
@{
/*
chapter 12 - SportsStore: Security & Finishing Touches
Securing the Administration Controller
Creating the View 312
Listing 12-9. The Contents of the Login.cshtml File
*/
ViewBag.Title = "Admin: Log In";
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<div class="panel">
<div class="panel-heading">
<h3> Log In</h3>
</div>
<div class="panel-body">
<p class="lead">Please log in to access the administration area:</p>
@using (Html.BeginForm())
{
@Html.ValidationSummary()
<div class="form-group">
<label>User Name:</label>
@Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
</div>
<div class="form-group">
<label>Password:</label>
@Html.PasswordFor(m => m.Password, new { @class = "form-control" })
</div>
<input type="submit" value="Log in" class="btn btn-primary" />
}
</div>
</div>
This is the AccountController
class:
using System.Web.Mvc;
using SportsStore.WebUI.Infrastructure.Abstract;
using SportsStore.WebUI.Models;
namespace SportsStore.WebUI.Controllers
{
/*
chapter 12 - SportsStore: Security & Finishing Touches
Securing the Administration Controller
Creating the Account Controller 312
Listing 12-8. The Contents of the AccountController.cs File
*/
public class AccountController : Controller
{
IAuthProvider authProvider;
public AccountController(IAuthProvider auth)
{
authProvider = auth;
}
[HttpPost]
public ActionResult Login(LoginViewModel model, string returnUrl)
{
if (authProvider.Authenticate(model.UserName, model.Password))
{
return Redirect(returnUrl ?? Url.Action("Index", "Admin"));
}
else
{
return View();
}
}
}
}
And here's the web.config
file:
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.7.2" />
<!--
chapter 12 - SportsStore: Security & Finishing Touches
Securing the Administration Controller
Creating a Basic Security Policy
Listing 12-1. Configuring Forms Authentication in the Web.config File
Listing 12-2. Defining a Username and Password in the Web.config File
-->
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880">
<credentials passwordFormat="Clear">
<user name="admin" password="secret" />
</credentials>
</forms>
</authentication>
</system.web>
Maybe my mistake is here? RouteConfig/RegisterRoutes
:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
null,
"",
new { controller = "Product", action = "List", category = (string)null, page = 1 }
);
routes.MapRoute(
null,
"Page{page}",
new { controller = "Product", action = "List", category = (string)null },
new { page = @"\d+" }
);
routes.MapRoute(
null,
"{category}",
new { controller = "Product", action = "List", page = 1 }
);
routes.MapRoute(
null,
"{category}/Page{page}",
new { controller = "Product", action = "List" },
new { page = @"\d+" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
When I run the web application I get this HTTP 404 message
Server error in application '/'
The resource cannot be found.
Request URL: Account/Login
What's my mistake?
You have a Login method on the AccountController that takes an HttpPost but in order to get the view you also need an HttpGet endpoint:
[HttpGet]
public ActionResult Login(string returnUrl)
{
return View();
}
With the appropriate Login.cshtml to show the login form of course.
Also make sure you have the following added to your RouteConfig
routes.MapMvcAttributeRoutes();