【发布时间】:2022-07-04 19:53:41
【问题描述】:
我有一个带有 Mvc REST Api 的 Angular 网站。我刚刚将它从 .net core 2.0 更新到最新的 .Net 6,以及 EF Core 和 AspNetCore.Identity。
我有一个扩展的 AspNetCore 的 IdentityUser。当我尝试更新它时,发送了 2 个更新请求(我使用 Sql Server Profiler 发现了) - 一个包含更新的列,另一个将其重置为原始值。它只发生在 IdentityUser 上,其他实体正常工作。结果,我无法更新任何用户。
它们有时会以不同的顺序出现,因此有时更新确实有效(但更多时候无效)。
例如当我尝试这样的事情时
var user = await UserAccountManager.UserManager.FindByIdAsync(id);
user.Name = model.Name;
var result = await UserAccountManager.UserManager.UpdateAsync(user);
如您所见,有 2 个后续更新,它们的名称字段和 ConcurrencyStamp 不同。
我尝试直接从上下文中获取用户,例如:
var xx = await Context.Users.SingleOrDefaultAsync(m => m.Id == id);
xx.Name = model.Name;
var aa = await Context.SaveChangesAsync();
同样的事情。
即使将其全部包装在事务中也不起作用 - SQL 请求被分离出来,但在更新用户之后,仍然发送了另一个 SQL 查询将其还原。
如果有帮助,我将粘贴到 ConfigureServices 函数中(来自 Startup.cs):
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddNewtonsoftJson(options => {
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
services.AddDbContext<OffWorkDbContext>(options =>
{
options.UseSqlServer(Configuration["ConnectionStrings:DefaultConnection"], b => b.MigrationsAssembly("Hicron.OffWorkPlanner.DataAccessComponent"));
});
// add identity
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<OffWorkDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(o =>
{
// User settings
o.User.RequireUniqueEmail = true;
o.Password.RequireDigit = false;
o.Password.RequireNonAlphanumeric = false;
o.Password.RequireUppercase = false;
o.Password.RequireLowercase = false;
//o.ClaimsIdentity.UserNameClaimType = OpenIdConnectConstants.Claims.Name;
//o.ClaimsIdentity.UserIdClaimType = OpenIdConnectConstants.Claims.Subject;
//o.ClaimsIdentity.RoleClaimType = OpenIdConnectConstants.Claims.Role;
});
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Token:Issuer"],
ValidAudience = Configuration["Token:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration["Token:Key"]))
};
});
services.AddAuthorization(options =>
{
//add authorization policies
options.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser().Build());
});
Mapper.Initialize(cfg =>
{
cfg.AddProfile<AutoMapperProfile>();
});
// Add cors
services.AddCors();
// Add framework services.
services.AddMvc(options =>
{
options.EnableEndpointRouting = false;
});
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
services.Configure<EmailConfig>(Configuration.GetSection("SmtpConfig"));
services.AddScoped<IEmailNotifications, EmailNotifications>();
services.AddScoped<IUserAccountManager, UserAccountManager>();
services.AddScoped<ITeamService, TeamService>();
services.AddScoped<IUserService, UserService>();
services.AddScoped<IDayService, DayService>();
services.AddScoped<IProjectService, ProjectService>();
services.AddScoped<IUserCalendarItemService, UserCalendarItemService>();
services.AddScoped<IDepartmentService, DepartmentService>();
services.AddTransient<IDatabaseInitializer, DatabaseInitializer>();
}
请帮我弄清楚这里发生了什么(并更新用户)。
【问题讨论】:
-
您收到的异常/消息是什么?
-
偶尔我会收到 DbUpdateConcurrencyException(如果您有 2 个更新混在一起,这是有道理的),但总的来说我没有收到。
标签: .net asp.net-mvc entity-framework-core asp.net-identity