2
votes

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.

Error occurring when login service call using HttpClient.

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?

1
How you're calling your GET and Login methods?Anuraj
As you state yourself it's the difference between "development" and "production". You did not elaborate on that. What do you call "production" ? How do you run it in development? What profile?Henk Holterman
Development mode is when I'm running the code through Visual Studio using IIS Express and debugging the code. For production mode, I published the application in a folder and created a website using the local IIS, following the tips that Microsoft has in its documentation here -> docs.microsoft.com/pt-br/aspnet/core/host-and-deploy/iis/….Luiz Eugênio Barbieri
Have you tried PostMan to test/investigate your API ?Henk Holterman

1 Answers

2
votes

I solved the problem. I surrounded the login service with a try catch and started to return the stacktrace. With that I noticed that the error was in the connecion string, I had not informed the database login and password. In development mode, it is not necessary to enter the database login and password, but in production this is mandatory. Thanks everyone for the tips = D