Я пытался получить переменную сеанса в классе обслуживания, установленном через DI в приложении ASP.NET Core 2.0.Мне нужно использовать переменную сеанса "StruturePath" для глобального фильтра в ядре структуры сущностей, а переменная сеанса задается через Login POST Action.Но это вызывает исключение для публичной строки GetStructurePath ().
Исключение
System.InvalidOperationException: 'Session has not been configured for this application or request.'
Мне не нравится идея использовать HttpContext непосредственно в DbContext.Любые предложения будут полезны или любой лучший подход для достижения этой цели.Спасибо
public class UserService
{
private readonly IHttpContextAccessor contextAccessor;
public UserService(IHttpContextAccessor contextAccessor)
{
this.contextAccessor = contextAccessor;
}
public string GetStructurePath()
{
return contextAccessor?.HttpContext?.Session?.GetString("StructurePath");
}
}
Startup.cs
public class Startup
{
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
Configuration = configuration;
Environment = env;
}
public IHostingEnvironment Environment { get; }
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.AddSingleton<IConfiguration>(Configuration);
// services.AddDbContext<ApplicationDbContext>(options =>
// options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddSingleton<IStringLocalizerFactory, EfStringLocalizerFactory>();
//services.AddScoped(typeof(IEntityRepository<>), typeof(EntityRepository<>));
//services.AddScoped<IMessageRepository, MessageRepository>();
services.AddScoped<PersonService>();
services.AddTransient<IHttpContextAccessor,HttpContextAccessor>();
services.AddTransient<UserService>();
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddScoped<IDbFactory, DbFactory>();
services.AddScoped<IDbInitializer, DbInitializer>();
services.AddScoped<IDisposable, Disposable>();
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
services.AddScoped<CultureService>();
services.AddLocalization(options =>
{
//options.ResourcesPath = "Resources";
});
var supportedCultures = new[]
{
new CultureInfo(ApplicatonSettings.ItalianCulture),
new CultureInfo(ApplicatonSettings.EnglishCulture),
};
services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new RequestCulture(ApplicatonSettings.ItalianCulture);
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders = new List<IRequestCultureProvider>
{
//new QueryStringRequestCultureProvider(),
new CookieRequestCultureProvider()
};
});
services.AddMvc()
.AddSessionStateTempDataProvider()
.AddViewLocalization(LanguageViewLocationExpanderFormat.SubFolder)
.AddDataAnnotationsLocalization();
// Adds a default in-memory implementation of IDistributedCache.
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
// Set a short timeout for easy testing.
//options.IdleTimeout = TimeSpan.FromSeconds(1000);
//options.Cookie.HttpOnly = true;
});
// Mapper.Initialize(cfg => cfg.AddProfile<AutoMapperProfile>());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IDbInitializer dbInitializer)
{
ApplicatonSettings.ConnectionString = Configuration.GetConnectionString("DefaultConnection");
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
//app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseRequestLocalization();
app.UseAuthentication();
dbInitializer.Initialize();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");///
});
}
}
ApplicationDbContext.cs
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
private string _hierarchy;
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, UserService userService)
: base(options)
{
if(userService != null)
{
_hierarchy = userService.GetStructurePath();
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//model
if (string.IsNullOrEmpty(_hierarchy) == false)
{
modelBuilder.Entity<PersonStruct>().HasQueryFilter(e => e.Hierarchy.StartsWith(_hierarchy));
}
base.OnModelCreating(modelBuilder);
}