Невозможно вызвать контроллер из клиента с шаблоном Blazor по умолчанию с включенным автоматическим рендерингом и предваC#

Место общения программистов C#
Ответить
Anonymous
 Невозможно вызвать контроллер из клиента с шаблоном Blazor по умолчанию с включенным автоматическим рендерингом и предва

Сообщение Anonymous »

Я только начинаю возиться с новым шаблоном Blazor по умолчанию с глобальным включенным автоматическим рендерингом и включенным предварительным рендерингом. Мой компонент Login.Razor находится в клиентском проекте. Я хочу, чтобы когда я ввожу имя пользователя и пароль и нажимаю кнопку входа в систему, я использую HttpClient для выполнения почтового вызова к конечной точке входа AuthController > в серверном проекте, который находится в том же решении. Звучит так, будто это должно быть просто, не так ли? LOL.
Я изо всех сил пытаюсь заставить HttpClient заполнить базовый адрес и фактически выполнить вызов. Я просматривал несколько сообщений StackOverflow, Github Copilot, Chat Gpt и т. д. в течение нескольких дней. Кажется, ничего не помогает.
Насколько я понимаю, Сервер отображает компонент в первый раз и загружает файлы в браузер, чтобы при последующих загрузках страницы компонент можно было визуализировать в браузер.
Я читал, что мне нужны службы на клиенте и сервере, в моем случае для входа в систему. Клиентская служба вызовет API, а серверная служба осуществит вход в систему, естественно, минуя контроллер. Я не уверен, как это сделать. Во-первых, я хочу сохранить токен в локальном хранилище.
Вот мой текущий код:
Client Starup.cs

Код: Выделить всё

var builder = WebAssemblyHostBuilder.CreateDefault(args);

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

builder.Services.AddBlazoredLocalStorage();

builder.Services.AddScoped();

await builder.Build().RunAsync();
Login.razor

Код: Выделить всё

@inject IJSRuntime JS
@inject IBaseHttpService HttpService

@code {
private LoginModel loginModel = new LoginModel();

private async Task HandleLogin()
{
//HttpClient client = ClientFactory.CreateClient();
// HttpClient client1 = ClientFactory.CreateClient("MyHttpClient");

var response = await HttpService.Post(loginModel, "api/auth/login");
if (response.Success)
{
var result = response.Data;
await JS.InvokeVoidAsync("localStorage.setItem", "authToken", result);
// Redirect or perform other actions after successful login
}
else
{
// Handle login failure
}
}

public class LoginResult
{
public string Token { get; set; }
}
}
Клиентская базаHttpService

Код: Выделить всё

public class BaseHttpService : IBaseHttpService
{
public readonly HttpClient client;
public readonly ILocalStorageService localStorage;

public BaseHttpService(HttpClient client, ILocalStorageService localStorage)
{
this.client = client;
this.localStorage = localStorage;
}

public async Task Post(T model, string endPoint)
{
Response response;
try
{
var user = System.Text.Json.JsonSerializer.Serialize(model);
var requestContent = new StringContent(user, Encoding.UTF8, "application/json");

var responseMessage = await client.PostAsync(endPoint, requestContent);

if (responseMessage.IsSuccessStatusCode)
{
var jsonString = responseMessage.Content.ReadAsStringAsync().Result;
var myObject = JsonConvert.DeserializeObject(jsonString);

response = new Response
{
Data = myObject!,
Success = true,
};

return response;
}
else
{
return new Response { Data = (T)Activator.CreateInstance(typeof(T))!, Message = responseMessage.ReasonPhrase ?? string.Empty, Success = false };
}
}
catch (Exception)
{
throw;
}

return response;
}
}
сокращенно Server Startup.cs

Код: Выделить всё

...
builder.Services.AddScoped();

...

// Add CORS services
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAll", builder =>
{
_ = builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});

...
// Use CORS policy
app.UseCors("AllowAll");
Контроллер

Код: Выделить всё

[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
private readonly UserManager _userManager;
private readonly SignInManager _signInManager;
private readonly IConfiguration _configuration;

public AuthController(UserManager userManager, SignInManager signInManager, IConfiguration configuration)
{
_userManager = userManager;
_signInManager = signInManager;
_configuration = configuration;
}

[HttpPost("login")]
public async Task Login([FromBody] LoginModel model)
{
var user = await _userManager.FindByNameAsync(model.Username);
if (user != null &&  await _userManager.CheckPasswordAsync(user, model.Password))
{
var token = GenerateJwtToken(user);
return Ok(new { token });
}
return Unauthorized();
}

private string GenerateJwtToken(ApplicationUser user)
{
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())
};

var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

var token = new JwtSecurityToken(
issuer: _configuration["Jwt:Issuer"],
audience: _configuration["Jwt:Audience"],
claims: claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);

return new JwtSecurityTokenHandler().WriteToken(token);
}
}
Что мне нужно сделать? Я знаю, что можно было бы значительно упростить эту задачу, отключив предварительный рендеринг, но я хотел бы попытаться заставить его работать с включенным предварительным рендерингом.
Думаю, мне действительно нужно выяснить следующее: , когда сервер отобразил компонент входа в систему, как мне реализовать вход без вызова контроллера. Я этого не понимаю.
Спасибо.
Редактировать: я понял это и хотел поделиться решением< /п>

Подробнее здесь: https://stackoverflow.com/questions/793 ... h-auto-ren
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»