I set up my own home lab to learn development in the hopes of proving my competence. I am using VSCode to write the code with help from AI. I use Github as my repository: https://github.com/JonathanHoward86/BackendDevProject I use Azure Devops for my CI/CD I use Azure Web Services for the Web App: learnhowtodev.azurewebsites.net and SQL database.
For some reason, in the last couple of days my database has stopped writing user registrations or logins. This post is specifically asking about the Register function to keep it simple.
The views all load, the url's redirect correcty, but the Login and Register buttons are not redirecting and the database is not storing any of the login info provided by the user when clicking Register and this was working just last week.
I am not receiving any error in the Web App Log Stream, no error in the Dev Console... Just a 200 Post and then the page refreshes which means it's failing but I have no idea why...
I've gone over my commits to see if there was something I changed that would cause this but I can't identify anything.
Any advice?
This is my Account Controller:
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using MyEcommerceBackend.Models;
using SendGrid;
using SendGrid.Helpers.Mail;
namespace MyEcommerceBackend.Controllers
{
[Route("[controller]")]
public class AccountController : Controller
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly IConfiguration _configuration;
public AccountController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager, IConfiguration configuration)
{
_userManager = userManager;
_signInManager = signInManager;
_configuration = configuration;
}
[HttpPost("Register")]
public async Task<IActionResult> Register(RegisterModel model)
{
if (ModelState.IsValid)
{
if (model.Email != null && model.Password != null)
{
var user = new IdentityUser { UserName = model.Email, Email = model.Email };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, false);
return RedirectToAction("RegisterSuccess", "View");
}
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error.Description);
}
}
else
{
ModelState.AddModelError("", "Email and Password must not be null");
}
}
return View("Register", model);
}
This is my Register Model:
using System.ComponentModel.DataAnnotations;
namespace MyEcommerceBackend.Models
{
public class RegisterModel // Model for user registration.
{
[Required]
[EmailAddress]
public string? Email { get; set; } // Required email property.
[Required]
[MinLength(6)] // Minimum length for a password, change as needed.
public string? Password { get; set; } // Required password property.
[Compare("Password")] // Ensures this matches the password field.
public string? ConfirmPassword { get; set; } // Required confirm password property.
}
}
This is my View Controller:
using Microsoft.AspNetCore.Mvc;
using MyEcommerceBackend.Models;
public class ViewController : Controller // Controller for handling user-facing views like Register, Login, etc.
{
[HttpGet]
public IActionResult Register()
{
return View(); // Returns the Register view.
}
[HttpPost]
public IActionResult Register(RegisterModel model)
{
return View(model); // Returns the Register view along with the model data.
}
public IActionResult RegisterSuccess()
{
return View(); // Returns the RegisterSuccess view.
}
This is my main program.cs:
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using MyEcommerceBackend.Models;
namespace MyEcommerceBackend
{
public class Authentication
{
// Main method - entry point of the application
public static void Main(string[] args)
{
// Creates and runs the web host
CreateHostBuilder(args).Build().Run();
}
// Defines the host builder
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
// Configures the web host to use this class (Authentication) as the startup class
webBuilder.UseStartup<Authentication>();
});
// Constructor that accepts configuration settings
public Authentication(IConfiguration configuration)
{
Configuration = configuration;
}
// Configuration property
public IConfiguration Configuration { get; }
// ConfigureServices method - used to register application services
public void ConfigureServices(IServiceCollection services)
{
// Read the environment variables from Azure
string server = Configuration["DBServer"] ?? throw new Exception("Server environment variable is not set.");
string database = Configuration["DB"] ?? throw new Exception("Database environment variable is not set.");
string username = Configuration["DBLogin"] ?? throw new Exception("Username environment variable is not set.");
string password = Configuration["DBPW"] ?? throw new Exception("Password environment variable is not set.");
// Construct the connection string
string connectionString = $"Server=tcp:{server},1433;Initial Catalog={database};Persist Security Info=False;User ID={username};Password={password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;";
// Add the DbContext using the connection string
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
// Registers controller services
services.AddControllers();
// Add MVC support with Views and Controllers
services.AddControllersWithViews();
// Adds Identity services for authentication and authorization
services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Configures API explorer and Swagger for API documentation
services.AddEndpointsApiExplorer();
services.AddSwaggerGen();
}
// Configure method - used to configure the HTTP request pipeline
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// Enables Swagger in the development environment
if (env.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(); // Enables Swagger UI for API documentation browsing
}
// Adds routing middleware
app.UseRouting();
// Adds authentication and authorization middleware
app.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles(); // Serve static files like CSS, JavaScript, etc.
// Enable endpoint routing and configure the default route
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=View}/{action=Login}/{id?}"); // Defines the default route
endpoints.MapControllers();
});
}
}
}
This is the Register View:
<!DOCTYPE html>
<html lang="en">
@{
ViewData["Title"] = "Please enter your Email and Password then click Register.";
}
<h2>@ViewData["Title"]</h2>
<form method="post" asp-controller="Account" asp-action="Register">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="email-label">Email:</span>
</div>
<input type="text" class="form-control" id="Email" name="Email" aria-describedby="email-label" required autocomplete="email">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="password-label">Password:</span>
</div>
<input type="password" class="form-control" id="Password" name="Password" aria-describedby="password-label" required autocomplete="new-password">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="confirm-password-label">Confirm Password:</span>
</div>
<input type="password" class="form-control" id="ConfirmPassword" name="ConfirmPassword" aria-describedby="confirm-password-label" required autocomplete="new-password">
</div>
<button type="submit" class="btn btn-primary mb-3">Register</button>
</form>
</html>
This is a screenshot of the dev console log when I tried to Register: Network Dev Tools, no errors or warnings or issues, 200POST
Reproduction Steps: Open my website in chrome browser. Click Register button. Fill in an email, password, and password confirmation. Click Register
Expected Result: Redirected to success page and information stored in the database.
Actual Result: Page refreshes, a 200 Post shown in the Dev Tool, no errors of any kind.
Turned out that logging was indeed the issue, not sure if it was what was suggest, but I did remove the logging I was using and switched to NLog and magically the redirects began to work. I had to setup a local environment and DB / SMTP to test it all, but it does now work correctly.
Hopefully this helps someone somewhere. :)
Updated Registration Controller:
Updated Register Model:
Updated Register View:
Updated Program and Startup: