Asp.net core 在httpContextAccessor.HttpContext上返回null
我们重写saveChangesSync()以自动更新DateCreated、CreatedBy、LastDateModified和LastModifiedBy。使用CreatedBy和LastModifiedBt,我们需要输入标识的用户Id 在ApplicationDbContext的构造函数中,我们添加了如下内容:Asp.net core 在httpContextAccessor.HttpContext上返回null,asp.net-core,.net-core,asp.net-core-2.0,Asp.net Core,.net Core,Asp.net Core 2.0,我们重写saveChangesSync()以自动更新DateCreated、CreatedBy、LastDateModified和LastModifiedBy。使用CreatedBy和LastModifiedBt,我们需要输入标识的用户Id 在ApplicationDbContext的构造函数中,我们添加了如下内容: \u userName=httpContextAccessor.HttpContext.User.Identity.Name; //_userID=userManager.GetU
\u userName=httpContextAccessor.HttpContext.User.Identity.Name;
//_userID=userManager.GetUserId(httpContext.httpContext.User)代码>
。。并始终在此httpContextAccessor.HttpContext中获取空值。有什么想法吗?我们在下面列出了来源
环境:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using AthlosifyWebArchery.Models;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
namespace AthlosifyWebArchery.Data
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
{
private readonly string _userID;
private readonly string _userName;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options,
IHttpContextAccessor httpContextAccessor
)
: base(options)
{
_userName = httpContextAccessor.HttpContext.User.Identity.Name;
//_userID = userManager.GetUserId(httpContext.HttpContext.User);
}
public DbSet<AthlosifyWebArchery.Models.TournamentBatchItem> TournamentBatchItem { get; set; }
public DbSet<AthlosifyWebArchery.Models.TournamentBatch> TournamentBatch { get; set; }
public virtual DbSet<AthlosifyWebArchery.Models.Host> Host { get; set; }
public DbSet<AthlosifyWebArchery.Models.HostApplicationUser> HostApplicationUser { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
foreach (var entityType in builder.Model.GetEntityTypes())
{
// 1. Add the IsDeleted property
entityType.GetOrAddProperty("IsDeleted", typeof(bool));
// 2. Create the query filter
var parameter = Expression.Parameter(entityType.ClrType);
// EF.Property<bool>(post, "IsDeleted")
var propertyMethodInfo = typeof(EF).GetMethod("Property").MakeGenericMethod(typeof(bool));
var isDeletedProperty = Expression.Call(propertyMethodInfo, parameter, Expression.Constant("IsDeleted"));
// EF.Property<bool>(post, "IsDeleted") == false
BinaryExpression compareExpression = Expression.MakeBinary(ExpressionType.Equal, isDeletedProperty, Expression.Constant(false));
// post => EF.Property<bool>(post, "IsDeleted") == false
var lambda = Expression.Lambda(compareExpression, parameter);
builder.Entity(entityType.ClrType).HasQueryFilter(lambda);
}
// Many to Many relationship
builder.Entity<HostApplicationUser>()
.HasKey(bc => new { bc.HostID, bc.Id });
builder.Entity<HostApplicationUser>()
.HasOne(bc => bc.Host)
.WithMany(b => b.HostApplicationUsers)
.HasForeignKey(bc => bc.HostID);
builder.Entity<HostApplicationUser>()
.HasOne(bc => bc.ApplicationUser)
.WithMany(c => c.HostApplicationUsers)
.HasForeignKey(bc => bc.Id);
}
public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
OnBeforeSaving();
return base.SaveChanges(acceptAllChangesOnSuccess);
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
{
OnBeforeSaving();
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
private void OnBeforeSaving()
{
// Added
var added = ChangeTracker.Entries().Where(v => v.State == EntityState.Added && typeof(IBaseEntity).IsAssignableFrom(v.Entity.GetType())).ToList();
added.ForEach(entry =>
{
((IBaseEntity)entry.Entity).DateCreated = DateTime.UtcNow;
((IBaseEntity)entry.Entity).CreatedBy = _userID;
((IBaseEntity)entry.Entity).LastDateModified = DateTime.UtcNow;
((IBaseEntity)entry.Entity).LastModifiedBy = _userID;
});
// Modified
var modified = ChangeTracker.Entries().Where(v => v.State == EntityState.Modified &&
typeof(IBaseEntity).IsAssignableFrom(v.Entity.GetType())).ToList();
modified.ForEach(entry =>
{
((IBaseEntity)entry.Entity).LastDateModified = DateTime.UtcNow;
((IBaseEntity)entry.Entity).LastModifiedBy = _userID;
});
// Deleted
//var deleted = ChangeTracker.Entries().Where(v => v.State == EntityState.Deleted &&
//typeof(IBaseEntity).IsAssignableFrom(v.Entity.GetType())).ToList();
var deleted = ChangeTracker.Entries().Where(v => v.State == EntityState.Deleted).ToList();
deleted.ForEach(entry =>
{
((IBaseEntity)entry.Entity).DateDeleted = DateTime.UtcNow;
((IBaseEntity)entry.Entity).DeletedBy = _userID;
});
foreach (var entry in ChangeTracker.Entries()
.Where(e => e.State == EntityState.Deleted &&
e.Metadata.GetProperties().Any(x => x.Name == "IsDeleted")))
{
switch (entry.State)
{
case EntityState.Added:
entry.CurrentValues["IsDeleted"] = false;
break;
case EntityState.Deleted:
entry.State = EntityState.Modified;
entry.CurrentValues["IsDeleted"] = true;
break;
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using AthlosifyWebArchery.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using AthlosifyWebArchery.Models;
using DinkToPdf.Contracts;
using DinkToPdf;
namespace AthlosifyWebArchery
{
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.
public void ConfigureServices(IServiceCollection services)
{
//services.AddHttpContextAccessor();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
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.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
// Extended Application User from IdentityUser
// and ApplicationRole from IdentityRole
services.AddIdentity<ApplicationUser, ApplicationRole>(
options => options.Stores.MaxLengthForKeys = 128)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeFolder("/Tournaments");
options.Conventions.AuthorizeFolder("/TournamentAtheletes");
options.Conventions.AuthorizeFolder("/TournamentBatches");
options.Conventions.AuthorizeFolder("/TournamentContingents");
options.Conventions.AuthorizeFolder("/Admin");
//options.Conventions.AuthorizeFolder("/Private");
//options.Conventions.AllowAnonymousToPage("/Private/PublicPage");
//options.Conventions.AllowAnonymousToFolder("/Private/PublicPages");
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ApplicationDbContext context,
RoleManager<ApplicationRole> roleManager,
UserManager<ApplicationUser> userManager)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc();
//UserManagerInitialData.Initialize(context, userManager, roleManager).Wait();
}
}
}
.NET核心2.1
SQL Server
ApplicationDBContext.cs:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using AthlosifyWebArchery.Models;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
namespace AthlosifyWebArchery.Data
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
{
private readonly string _userID;
private readonly string _userName;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options,
IHttpContextAccessor httpContextAccessor
)
: base(options)
{
_userName = httpContextAccessor.HttpContext.User.Identity.Name;
//_userID = userManager.GetUserId(httpContext.HttpContext.User);
}
public DbSet<AthlosifyWebArchery.Models.TournamentBatchItem> TournamentBatchItem { get; set; }
public DbSet<AthlosifyWebArchery.Models.TournamentBatch> TournamentBatch { get; set; }
public virtual DbSet<AthlosifyWebArchery.Models.Host> Host { get; set; }
public DbSet<AthlosifyWebArchery.Models.HostApplicationUser> HostApplicationUser { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
foreach (var entityType in builder.Model.GetEntityTypes())
{
// 1. Add the IsDeleted property
entityType.GetOrAddProperty("IsDeleted", typeof(bool));
// 2. Create the query filter
var parameter = Expression.Parameter(entityType.ClrType);
// EF.Property<bool>(post, "IsDeleted")
var propertyMethodInfo = typeof(EF).GetMethod("Property").MakeGenericMethod(typeof(bool));
var isDeletedProperty = Expression.Call(propertyMethodInfo, parameter, Expression.Constant("IsDeleted"));
// EF.Property<bool>(post, "IsDeleted") == false
BinaryExpression compareExpression = Expression.MakeBinary(ExpressionType.Equal, isDeletedProperty, Expression.Constant(false));
// post => EF.Property<bool>(post, "IsDeleted") == false
var lambda = Expression.Lambda(compareExpression, parameter);
builder.Entity(entityType.ClrType).HasQueryFilter(lambda);
}
// Many to Many relationship
builder.Entity<HostApplicationUser>()
.HasKey(bc => new { bc.HostID, bc.Id });
builder.Entity<HostApplicationUser>()
.HasOne(bc => bc.Host)
.WithMany(b => b.HostApplicationUsers)
.HasForeignKey(bc => bc.HostID);
builder.Entity<HostApplicationUser>()
.HasOne(bc => bc.ApplicationUser)
.WithMany(c => c.HostApplicationUsers)
.HasForeignKey(bc => bc.Id);
}
public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
OnBeforeSaving();
return base.SaveChanges(acceptAllChangesOnSuccess);
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
{
OnBeforeSaving();
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
private void OnBeforeSaving()
{
// Added
var added = ChangeTracker.Entries().Where(v => v.State == EntityState.Added && typeof(IBaseEntity).IsAssignableFrom(v.Entity.GetType())).ToList();
added.ForEach(entry =>
{
((IBaseEntity)entry.Entity).DateCreated = DateTime.UtcNow;
((IBaseEntity)entry.Entity).CreatedBy = _userID;
((IBaseEntity)entry.Entity).LastDateModified = DateTime.UtcNow;
((IBaseEntity)entry.Entity).LastModifiedBy = _userID;
});
// Modified
var modified = ChangeTracker.Entries().Where(v => v.State == EntityState.Modified &&
typeof(IBaseEntity).IsAssignableFrom(v.Entity.GetType())).ToList();
modified.ForEach(entry =>
{
((IBaseEntity)entry.Entity).LastDateModified = DateTime.UtcNow;
((IBaseEntity)entry.Entity).LastModifiedBy = _userID;
});
// Deleted
//var deleted = ChangeTracker.Entries().Where(v => v.State == EntityState.Deleted &&
//typeof(IBaseEntity).IsAssignableFrom(v.Entity.GetType())).ToList();
var deleted = ChangeTracker.Entries().Where(v => v.State == EntityState.Deleted).ToList();
deleted.ForEach(entry =>
{
((IBaseEntity)entry.Entity).DateDeleted = DateTime.UtcNow;
((IBaseEntity)entry.Entity).DeletedBy = _userID;
});
foreach (var entry in ChangeTracker.Entries()
.Where(e => e.State == EntityState.Deleted &&
e.Metadata.GetProperties().Any(x => x.Name == "IsDeleted")))
{
switch (entry.State)
{
case EntityState.Added:
entry.CurrentValues["IsDeleted"] = false;
break;
case EntityState.Deleted:
entry.State = EntityState.Modified;
entry.CurrentValues["IsDeleted"] = true;
break;
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using AthlosifyWebArchery.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using AthlosifyWebArchery.Models;
using DinkToPdf.Contracts;
using DinkToPdf;
namespace AthlosifyWebArchery
{
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.
public void ConfigureServices(IServiceCollection services)
{
//services.AddHttpContextAccessor();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton(typeof(IConverter), new SynchronizedConverter(new PdfTools()));
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.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
// Extended Application User from IdentityUser
// and ApplicationRole from IdentityRole
services.AddIdentity<ApplicationUser, ApplicationRole>(
options => options.Stores.MaxLengthForKeys = 128)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeFolder("/Tournaments");
options.Conventions.AuthorizeFolder("/TournamentAtheletes");
options.Conventions.AuthorizeFolder("/TournamentBatches");
options.Conventions.AuthorizeFolder("/TournamentContingents");
options.Conventions.AuthorizeFolder("/Admin");
//options.Conventions.AuthorizeFolder("/Private");
//options.Conventions.AllowAnonymousToPage("/Private/PublicPage");
//options.Conventions.AllowAnonymousToFolder("/Private/PublicPages");
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ApplicationDbContext context,
RoleManager<ApplicationRole> roleManager,
UserManager<ApplicationUser> userManager)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc();
//UserManagerInitialData.Initialize(context, userManager, roleManager).Wait();
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统文本;
使用Microsoft.AspNetCore.Identity.EntityFrameworkCore;
使用Microsoft.EntityFrameworkCore;
使用AthlosifyWebArchery.模型;
使用System.Linq;
使用系统线程;
使用System.Threading.Tasks;
使用System.Linq.Expressions;
使用Microsoft.AspNetCore.Http;
使用Microsoft.AspNetCore.Identity;
命名空间AthlosifyWebArchery.Data
{
公共类ApplicationDbContext:IdentityDbContext
{
私有只读字符串_userID;
私有只读字符串\u用户名;
公共应用程序DBContext(DbContextOptions选项,
IHttpContextAccessor httpContextAccessor
)
:基本(选项)
{
_userName=httpContextAccessor.HttpContext.User.Identity.Name;
//_userID=userManager.GetUserId(httpContext.httpContext.User);
}
公共数据库集TournamentBatchItem{get;set;}
公共DbSet TournamentBatch{get;set;}
公共虚拟数据库集主机{get;set;}
公共DbSet主机应用程序用户{get;set;}
模型创建时受保护的覆盖无效(ModelBuilder)
{
基于模型创建(生成器);
foreach(builder.Model.GetEntityTypes()中的var entityType)
{
//1.添加IsDeleted属性
GetOrAddProperty(“IsDeleted”,typeof(bool));
//2.创建查询筛选器
var parameter=Expression.parameter(entityType.ClrType);
//EF.财产(后,“已删除”)
var propertyMethodInfo=typeof(EF).GetMethod(“Property”).MakeGenericMethod(typeof(bool));
var isDeletedProperty=Expression.Call(propertyMethodInfo,参数,Expression.Constant(“IsDeleted”);
//EF.Property(post,“IsDeleted”)==false
BinaryExpression compareExpression=Expression.MakeBinary(ExpressionType.Equal,isDeletedProperty,Expression.Constant(false));
//post=>EF.Property(post,“IsDeleted”)==false
var lambda=Expression.lambda(比较表达式,参数);
实体(entityType.ClrType).HasQueryFilter(lambda);
}
//多对多关系
builder.Entity()
.HasKey(bc=>new{bc.HostID,bc.Id});
builder.Entity()
.HasOne(bc=>bc.Host)
.WithMany(b=>b.HostApplicationUsers)
.HasForeignKey(bc=>bc.HostID);
builder.Entity()
.HasOne(bc=>bc.ApplicationUser)
.WithMany(c=>c.HostApplicationUsers)
.HasForeignKey(bc=>bc.Id);
}
公共覆盖int SaveChanges(bool acceptAllChangesOnSuccess)
{
onbeforecaving();
返回base.SaveChanges(AcceptalChangesOnSuccess);
}
public override Task savechangesync(bool acceptillchangesonsuccess,CancellationToken CancellationToken=default(CancellationToken))
{
onbeforecaving();
return base.saveChangesSync(acceptAllChangesOnSuccess,cancellationToken);
}
保存之前的私有void()
{
//增加
var added=ChangeTracker.Entries()。其中(v=>v.State==EntityState.added&&typeof(IBaseEntity).IsAssignableFrom(v.Entity.GetType()).ToList();
添加了.ForEach(条目=>
{
((IBaseEntity)entry.Entity).DateCreated=DateTime.UtcNow;
((IBaseEntity)entry.Entity).CreatedBy=\u userID;
((IBaseEntity)entry.Entity).LastDateModified=DateTime.UtcNow;
((IBaseEntity)entry.Entity).LastModifiedBy=\u userID;
});
//修改
var modified=ChangeTracker.Entries()。其中(v=>v.State==EntityState.modified&&
typeof(IBaseEntity).IsAssignableFrom(v.Entity.GetType()).ToList();
modified.ForEach(条目=>
{
((IBaseEntity)entry.Entity).LastDateModified=DateTime.UtcNow;
((IBaseEntity)entry.Entity).LastModifiedBy=\u userID;
});
//删除
//var deleted=ChangeTracker.Entries()。其中(v=>v.State==EntityState.deleted&&
//typeof(IBaseEntity).IsAssignableFrom(v.Entity.GetType()).ToList();
var deleted=ChangeTracker.Entries();
已删除。ForEach(条目=>
{
((IBaseEntity)entry.Entity).DateDeleted=DateTime.UtcNow;
((IBaseEntity)entry.Entity).DeletedBy=\u userID;
});
foreach(ChangeTracker.Entries()中的var条目)
.Where(e=>e.State==EntityState.Deleted&&
e、 Metadata.GetProperties().Any(x=>x.Name==“IsDeleted”))
{
开关(进入状态)
{
案例实体状态。添加:
entry.CurrentValues[“IsDeleted”]=false;
打破
案例实体状态。已删除:
entry.State=实体