Не могли бы вы помочь мне. Я пытаюсь использовать Blazor с MongoDb Identity и всегда получаю исключение: значение не может быть нулевым. (Имя параметра 'source'), когда я вызываю signInManager.SignInAsyn c (user, false);
Версия сервера MongoDB: 4.2.5
ASP. Net Core 3.1
Пакеты NuGet: AspNetCore.Identity.Mon go: 6.7.0 MongoDB.Driver: 2.10.3
Предварительные шаги: 1. Создайте простой проект Blazor Server без аутентификации. 2. Затем я просто добавляю AspNetCore.Identity.Mon go.
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.Configure<BookstoreDatabaseSettings>(Configuration.GetSection(nameof(BookstoreDatabaseSettings)));
services.AddSingleton<IBookstoreDatabaseSettings>(sp =>
sp.GetRequiredService<IOptions<BookstoreDatabaseSettings>>().Value);
services
.AddIdentityMongoDbProvider<ApplicationUser, ApplicationRole>(identityOptions =>
{
identityOptions.Password.RequiredLength = 1;
identityOptions.Password.RequireLowercase = false;
identityOptions.Password.RequireUppercase = false;
identityOptions.Password.RequireNonAlphanumeric = false;
identityOptions.Password.RequireDigit = false;
}, mongoIdentityOptions =>
{
mongoIdentityOptions.ConnectionString = Configuration.GetConnectionString("MongoDbDatabase");
})
.AddDefaultTokenProviders();
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
});
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
services.AddScoped<BookService>();
services.AddTransient<LoginService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
ApplicationUser.cs
public class ApplicationUser : MongoUser
{
public string Name { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public DateTime? Birthdate { get; set; }
public string Country { get; set; }
public string State { get; set; }
public string City { get; set; }
}
ApplicationRole.cs
public class ApplicationRole : MongoRole
{
}
RegisterNewUserData.cs
public class RegisterUserData
{
public string UserName { get; set; }
public string Gender { get; set; }
public string Password { get; set; }
public string ConfirmedPassword { get; set; }
}
LoginService.cs
public class LoginService
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IConfiguration _configuration;
private readonly RoleManager<ApplicationRole> _roleManager;
public LoginService(UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IConfiguration configuration,
RoleManager<ApplicationRole> roleManager)
{
_userManager = userManager;
_signInManager = signInManager;
_configuration = configuration;
_roleManager = roleManager;
}
public async Task<bool> LogIn(LoginUserData loginUser)
{
ApplicationUser user = await _userManager.FindByNameAsync(loginUser.UserName);
if (user != null)
{
try
{
var result2 = await _signInManager.PasswordSignInAsync(user.Email, loginUser.Password, loginUser.RememberMe, lockoutOnFailure: true);
if (result2.Succeeded)
{
return true;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
return false;
}
public async Task<bool> RegisterNewUser(RegisterUserData regUser)
{
string roleName = "Member";
var user = new ApplicationUser
{
Name = regUser.UserName,
UserName = regUser.UserName,
Email = regUser.UserName,
Gender = regUser.Gender,
LastName = "",
Country = "",
State = "",
City = ""
};
bool isRoleExists = await _roleManager.RoleExistsAsync(roleName);
if (isRoleExists == false)
{
var role = new ApplicationRole();
role.Name = roleName;
await _roleManager.CreateAsync(role);
}
var result = await _userManager.CreateAsync(user, regUser.Password);
if (result.Succeeded)
{
await _userManager.AddToRoleAsync(user, roleName);
var claims = new List<Claim>
{
new Claim("user", user.UserName),
new Claim("role", roleName)
};
result = await _userManager.AddClaimsAsync(user, claims);
if (result.Succeeded)
{
try
{
await _signInManager.SignInAsync(user, false);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
return true;
}
}
return false;
}
}
В процессе регистрации Пользователь, Роли и Требования созданы и успешно добавлены. Вот данные из MongoDb:
{
"_id": {
"$oid": "5e9df2819fecf83484901211"
},
"UserName": "M1@g.com",
"NormalizedUserName": "M1@G.COM",
"Email": "M1@g.com",
"NormalizedEmail": "M1@G.COM",
"EmailConfirmed": false,
"PasswordHash": "AQAAAAEAACcQAAAAEGdbk1EC4niPacknWuMDpbc+YRZP5CmvH0IaUIslo5/vcHplpJO/iWBU/6opCYsErQ==",
"SecurityStamp": "BOYJUYQFPMLMHJ6NFBHG64K4SC7WEF5W",
"ConcurrencyStamp": "e9133395-1eed-4757-91a5-a5fc1d699f5d",
"PhoneNumber": null,
"PhoneNumberConfirmed": false,
"TwoFactorEnabled": false,
"LockoutEnd": null,
"LockoutEnabled": true,
"AccessFailedCount": 0,
"AuthenticatorKey": null,
"Roles": [
"5e9df27c9fecf83484901210"
],
"Claims": [
{
"_id": 0,
"UserId": null,
"ClaimType": "user",
"ClaimValue": "M1@g.com"
},
{
"_id": 0,
"UserId": null,
"ClaimType": "role",
"ClaimValue": "Member"
}
],
"Logins": [],
"Tokens": [],
"RecoveryCodes": [],
"Name": "M1@g.com",
"LastName": "",
"Gender": "Male",
"Birthdate": null,
"Country": "",
"State": "",
"City": ""
}
Но когда процесс вызывает:
_signInManager.SignInAsync(user, false);
или:
await _signInManager.PasswordSignInAsync(user.Email, loginUser.Password, loginUser.RememberMe, lockoutOnFailure: true);
Я получил исключение: Значение не может быть нулевым (Имя параметра «источник») . Итак, что я пропустил?
Примечания, я использую то же решение с ASP. Net Core 2.1 + Razor Pages + MongoDb Identity, и это хорошо работает.