Как я могу использовать сессию в классе обслуживания для глобальных фильтров ядра объектной структуры? - PullRequest
0 голосов
/ 26 мая 2018

Я пытался получить переменную сеанса в классе обслуживания, установленном через 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);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...