Entity Framework не поддерживается на стороне клиента Blazor, поскольку вы не можете получить доступ к базе данных, находящейся на сервере, из браузера. Чтобы получить доступ к данным на сервере, вы должны использовать Web API и обращаться к нему из Blazor через Ajax (HttpClient).
Джошуа Франк:
So I'm not sure, but I can't find any scenario that would allow me to share EF objects between client and server--which is a major rationale for Blazor.
Общий проект позволяет вам определять объекты, которые вы можете использовать как на клиенте, так и на сервере. Например, вы можете определить свои объекты Model в проекте Shared и использовать их в Blazor и в своем веб-API.
Ниже приведена демонстрация того, как это сделать:
Определите объект LoginParameters в общем проекте:
namespace BlazorWithIdentity.Shared
{
public class LoginParameters
{
[Required]
public string UserName { get; set; }
[Required]
public string Password { get; set; }
public bool RememberMe { get; set; }
}
}
Определить контроллер авторизации. Проигнорируйте большую часть кода и обратите внимание на метод Login, который имеет единственный параметр с именем parameters и типа LoginParameters, который был определен в общем проекте.
namespace BlazorWithIdentity.Server.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class AuthorizeController : ControllerBase
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
public AuthorizeController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Login(LoginParameters parameters)
{
if(!ModelState.IsValid) return BadRequest(ModelState.Values.SelectMany(state => state.Errors)
.Select(error => error.ErrorMessage)
.FirstOrDefault());
var user = await _userManager.FindByNameAsync(parameters.UserName);
if (user == null) return BadRequest("User does not exist");
var singInResult = await _signInManager.CheckPasswordSignInAsync(user, parameters.Password, false);
if (!singInResult.Succeeded) return BadRequest("Invalid password");
await _signInManager.SignInAsync(user, parameters.RememberMe);
return Ok(BuildUserInfo(user));
}
}
}
Тип LoginParameters, определенный в общем проекте и используемый в Blazor. Обратите внимание, что другой класс с именем UserInfo должен быть определен в общем проекте
@functions{
private UserInfo userInfo;
// This instance is bound to a form view, and gets its values from the form, when the form is "submitted"
LoginParameters loginParameters { get; set; } = new LoginParameters();
string error { get; set; }
async Task OnSubmit()
{
error = null;
try
{
var stringContent = new StringContent(Json.Serialize(loginParameters), Encoding.UTF8, "application/json");
var result = await _httpClient.PostAsync("api/Authorize/Login", stringContent);
if (result.StatusCode == System.Net.HttpStatusCode.BadRequest) throw new Exception(await result.Content.ReadAsStringAsync());
result.EnsureSuccessStatusCode();
return Json.Deserialize<UserInfo>(await result.Content.ReadAsStringAsync());
uriHelper.NavigateTo("");
}
catch (Exception ex)
{
error = ex.Message;
}
}
}
Примечание. Цель приведенного выше кода - показать вам общий дизайн трех частей приложения. Я просто копирую и вставляю код, он определенно не завершен, и я надеюсь, что я не скопировал некоторые вещи, которые могут ввести вас в заблуждение. Однако, если у вас есть какие-либо вопросы, я буду рад ответить на них.