I'm doing some tests with Blazor WebAssembly App ASP.NET Core hosted. This is a template in a previous version, which delivers a solution with three projects, being the client, the server and the shared one. In this solution I am using Entity Framework to access the database and Identity Core to perform user registration and login.
For this, I implemented the following controller.
using BlazorAutoComplete.Shared.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
[Route("api/[controller]")]
[ApiController]
public class AccountController : ControllerBase
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly IConfiguration _configuration;
public AccountController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager, IConfiguration configuration)
{
this._userManager = userManager;
this._signInManager = signInManager;
this._configuration = configuration;
}
[HttpGet]
public string Get()
{
return $"AccountController :: {DateTime.Now.ToShortDateString()}";
}
[HttpPost("Login")]
public async Task<ActionResult<UserToken>> Login([FromBody] UserInfo userInfo)
{
var result = await _signInManager.PasswordSignInAsync(userInfo.Email, userInfo.Password, isPersistent: false, lockoutOnFailure: false);
if (result.Succeeded)
{
return await GenerateTokenAsync(userInfo);
}
else
{
return BadRequest(new { message = "Login inválido" });
}
}
I also have the registration method on this controller, but that is beside the point.
The problem I need help with: in development mode, all services work (login, registration and Get which returns only one string, accessed in "api/account"). However, when I publish my project, only that Get service works. When I try to access the login API, I get a 404 Not Found response.
The login method call.
@inject HttpClient http
@inject NavigationManager navigation
@inject TokenAuthenticationProvider authStateProvider
async Task FazerLogin()
{
try
{
var loginAsJson = JsonSerializer.Serialize(userInfo);
var httpResponse = await http.PostAsync("api/account/login", new StringContent(loginAsJson, Encoding.UTF8, "application/json"));
if (httpResponse.IsSuccessStatusCode)
{
var responseAsString = await httpResponse.Content.ReadAsStringAsync();
var loginResult = JsonSerializer.Deserialize<UserToken>(responseAsString, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
await authStateProvider.Login(loginResult.Token);
navigation.NavigateTo("/");
}
else
{
loginFalhou = true;
Mensagem = $"Não foi possível realizar o login do usuário. (Erro: {httpResponse.StatusCode})";
}
}
catch (Exception)
{
loginFalhou = true;
Mensagem = $"Não foi possível realizar o login do usuário...";
}
}
I used the PostAsync method to check if httpResponse was successful in communication. But I also tried to implement the method as follows:
async Task FazerLogin()
{
try
{
var loginResult = await http.PostJsonAsync<UserToken>("/api/account/login", userInfo);
await authStateProvider.Login(loginResult.Token);
navigation.NavigateTo("/");
}
catch (Exception ex)
{
Console.Write(ex);
}
}
But the error remains.
I understand that Blazor WebAssembly ASP.NET Core Hosted is a template in a previous version. But I believe the problem is in ASP.NET Core 3.1.
The only difference I notice between the services is that the service that works returns only one string. The login, registration and other controllers return a Task>. Is this the problem? If so, is there another way to implement the login?