How can I resolve a HTTP 405 error in my ASP.NET Core MVC web application using Identity for authentication and authorization?

Amra Akmadžić 40 Reputation points
2024-08-20T15:44:37.0933333+00:00

My asp.net core MVC web application uses Identity for authentication and authorization, but my login doesn't work. After entering data and pressing the button in login I get a HTTP 405 error and message "This page isn't working".

My view uses POST method inside <form> tag, as well as my controller.

Here is my Account Controller:


public class AccountController : Controller

{

    private readonly VjencanjeIzSnovaDbContext _context;

    private readonly UserManager<Korisnik> _userManager;

    private readonly SignInManager<Korisnik> _signInManager;

    public AccountController(UserManager<Korisnik> userManager, SignInManager<Korisnik> signInManager, VjencanjeIzSnovaDbContext context)

    {

        _userManager = userManager;

        _signInManager = signInManager;

        _context = context;

    }

    [HttpGet]

    [Route("login")]

    public IActionResult Login()

    {

        return View(new LoginViewModel());

    }

    [HttpPost]

    public async Task<IActionResult> Login(LoginViewModel model)

    {

        if (ModelState.IsValid)

        {

            var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false);

            if (result.Succeeded)

            {

                return RedirectToAction("Index", "Home");

            }

            ModelState.AddModelError(string.Empty, "Neuspješan pokušaj prijave.");

        }

        return View(model);

    }

}


    public class LoginViewModel

    {

        [Required]

        public string Email { get; set; }

        [Required]

        [DataType(DataType.Password)]

        public string Password { get; set; }

        

        public bool RememberMe { get; set; } = false;

        public LoginViewModel()

        {

            Email = string.Empty;

            Password = string.Empty;

        }

    }

}

Program.cs:


using Microsoft.AspNetCore.Authentication.Cookies;

using Microsoft.AspNetCore.Identity;

using Microsoft.AspNetCore.Mvc.Authorization;

using Microsoft.EntityFrameworkCore;

using Microsoft.Identity.Web;

using Microsoft.Identity.Web.UI;

using VjencanjeIzSnova_WebApp.Data;

using VjencanjeIzSnova_WebApp.Models;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("LocalDb") ?? throw new InvalidOperationException("Connection string 'LocalDb' not found.");

builder.Services.AddDbContext<VjencanjeIzSnovaDbContext>(options =>

    options.UseSqlite(connectionString));

builder.Services.AddDefaultIdentity<Korisnik>(options => options.SignIn.RequireConfirmedAccount = true).AddEntityFrameworkStores<VjencanjeIzSnovaDbContext>();

builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddIdentity<Korisnik, IdentityRole>(options =>

{

    options.Password.RequireDigit = true;

    options.Password.RequireLowercase = true;

    options.Password.RequireUppercase = true;

    options.Password.RequireNonAlphanumeric = true;

    options.Password.RequiredLength = 6;

    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);

    options.Lockout.MaxFailedAccessAttempts = 5;

    options.SignIn.RequireConfirmedAccount = true;

})

.AddEntityFrameworkStores<VjencanjeIzSnovaDbContext>()

.AddDefaultTokenProviders();

// Add services to the container.

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)

    .AddCookie(options =>

    {

        options.LoginPath = "/login";

        options.AccessDeniedPath = "/Account/AccessDenied";

    });

builder.Services.AddAuthorization();

builder.Services.AddControllersWithViews();

builder.Services.AddRazorPages();

var app = builder.Build();

// Configure the HTTP request pipeline.

if (!app.Environment.IsDevelopment())

{

    app.UseExceptionHandler("/Home/Error");

    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.

    app.UseHsts();

}

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(

    name: "default",

    pattern: "{controller=Home}/{action=Index}/{id?}");

app.MapRazorPages();

app.Run();

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,550 questions
{count} votes

Accepted answer
  1. Ping Ni-MSFT 4,335 Reputation points Microsoft Vendor
    2024-08-21T07:02:59.3833333+00:00

    Hi @Amra Akmadžić,

    405 Method Not Allowed means the url is correct but the request type is not correct.

    From your code, two possible situations will cause such HTTP error.

    Firstly, you backend code contains redirection. Be sure you contains an Index action with [HttpGet] in HomeController.

    Secondly, you define [Route] attribute in your MVC Controller, Attribute routes are processed first, and conventional routes are processed afterward. This will cause the issue the form action in your frontend is always /login instead of /account/login . Then you can see the form send Post request to /login which will receive 405 HTTP Error.

    User's image

    To resolve this, ensure that both the GET and POST methods share the same route:

    [HttpPost]
    [Route("login")]
    public async Task<IActionResult> Login(LoginViewModel model)
    {
    

    Ensure that the form in your Razor view uses the correct action and method attributes:

    <form asp-action="Login" asp-controller="Account" method="post">
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,
    Rena

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.