Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set and Get session variable in ASP.NET Boilerplate .NET Core v3

I'm trying to set variable value (selected option from a select component in angular) in some component to use it in another component and I don't want to use window.sessionStorage() by javascript I want to use session storage in the .NET core but the problem is I could set the variable value but when I want to get it, it didn't return the value.

Below is my Application Service Code

 public class MainProjectAppService : AsyncCrudAppService<MainProject, MainProjectDto,int,PagedAndSortedResultRequestDto,MainProjectDto>
    {



         private readonly IHttpContextAccessor _httpContextAccessor;


        public MainProjectAppService(IRepository<MainProject, int> repository, IHttpContextAccessor httpContextAccessor) : base(repository)
        {

            _httpContextAccessor = httpContextAccessor;
        }

        public void setVaraibleValurinSesseion(int ID)
        {
            _httpContextAccessor.HttpContext.Session.SetInt32("GID", ID);
        }

        public int getVaraibleValurFromSesseion()
        {
            return (int)_httpContextAccessor.HttpContext.Session.GetInt32("GID");

        }

And here is my Updated Startup.cs class code :


using System;
using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Castle.Facilities.Logging;
using Abp.AspNetCore;
using Abp.AspNetCore.Mvc.Antiforgery;
using Abp.Castle.Logging.Log4Net;
using Abp.Extensions;
using TTT.Configuration;
using TTT.Identity;
using Abp.AspNetCore.SignalR.Hubs;
using Abp.Dependency;
using Abp.Json;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.Http;

namespace TTT.Web.Host.Startup
{
    public class Startup
    {
        private const string _defaultCorsPolicyName = "localhost";

        private readonly IConfigurationRoot _appConfiguration;

        public Startup(IWebHostEnvironment env)
        {
            _appConfiguration = env.GetAppConfiguration();
        }

        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddDistributedMemoryCache(); //added this

            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromSeconds(10);
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = true;
            });//added this 
            //MVC
            services.AddControllersWithViews(
                options =>
                {
                    options.Filters.Add(new AbpAutoValidateAntiforgeryTokenAttribute());
                }
            ).AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.ContractResolver = new AbpMvcContractResolver(IocManager.Instance)
                {
                    NamingStrategy = new CamelCaseNamingStrategy()
                };
            });

                 services.AddHttpContextAccessor(); // added this but no need as //I think

            services.AddMvc().AddSessionStateTempDataProvider();//added this
            services.AddSession();// added this 

            IdentityRegistrar.Register(services);
            AuthConfigurer.Configure(services, _appConfiguration);

            services.AddSignalR();

            // Configure CORS for angular2 UI
            services.AddCors(
                options => options.AddPolicy(
                    _defaultCorsPolicyName,
                    builder => builder
                        .WithOrigins(
                            // App:CorsOrigins in appsettings.json can contain more than one address separated by comma.
                            _appConfiguration["App:CorsOrigins"]
                                .Split(",", StringSplitOptions.RemoveEmptyEntries)
                                .Select(o => o.RemovePostFix("/"))
                                .ToArray()
                        )
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials()
                )
            );

            // Swagger - Enable this line and the related lines in Configure method to enable swagger UI
            services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc("v1", new OpenApiInfo() { Title = "TTT API", Version = "v1" });
                options.DocInclusionPredicate((docName, description) => true);

                // Define the BearerAuth scheme that's in use
                options.AddSecurityDefinition("bearerAuth", new OpenApiSecurityScheme()
                {
                    Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey
                });
            });

            // Configure Abp and Dependency Injection
            return services.AddAbp<TTTWebHostModule>(
                // Configure Log4Net logging
                options => options.IocManager.IocContainer.AddFacility<LoggingFacility>(
                    f => f.UseAbpLog4Net().WithConfig("log4net.config")
                )
            );
        }

        public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
        {

            app.UseAbp(options => { options.UseAbpRequestLocalization = false; }); // Initializes ABP framework.

            app.UseCors(_defaultCorsPolicyName); // Enable CORS!

            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();

            app.UseAbpRequestLocalization();
            //app.UseHttpContextItemsMiddleware();
             app.UseSession(); // <================= I've added this without it //will not work 
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<AbpCommonHub>("/signalr");
                endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
                endpoints.MapControllerRoute("defaultWithArea", "{area}/{controller=Home}/{action=Index}/{id?}");
            });

            // Enable middleware to serve generated Swagger as a JSON endpoint
            app.UseSwagger();
            // Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)
            app.UseSwaggerUI(options =>
            {
                options.SwaggerEndpoint(_appConfiguration["App:ServerRootAddress"].EnsureEndsWith('/') + "swagger/v1/swagger.json", "TTT API V1");
                options.IndexStream = () => Assembly.GetExecutingAssembly()
                    .GetManifestResourceStream("TTT.Web.Host.wwwroot.swagger.ui.index.html");
            }); // URL: /swagger
        }
    }
}

Update 3:


Now after added some configuration in Startup.cs class it works by Swagger but I wanna get the value by angular front it as following it returns

System.InvalidOperationException: 'Nullable object must have a value.'

angular set code :

   this.http.post('http://localhost:21021/api/services/app/MainProject/setVaraibleValurinSesseion?ID=555',{ID:555}).subscribe(data=>{
  alert('saved');
});

angular get code :

  this.http.get('http://localhost:21021/api/services/app/MainProject/getVaraibleValurFromSesseion').subscribe(data=>{
  console.log("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
      console.log(data);
      console.log(("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"));
});
like image 779
Abdulaziz Avatar asked Feb 21 '20 12:02

Abdulaziz


1 Answers

After reviewing your code I see you don't initialize the session services in the startup. To initialize the Session you need to provide a distributed cache service and setup the session services. Here is just the sample configuration bits you need to add in the startup from the official documentation.

public void ConfigureServices(IServiceCollection services)
{
   services.AddDistributedMemoryCache();

   services.AddSession(options =>
   {
      options.IdleTimeout = TimeSpan.FromSeconds(10);
      options.Cookie.HttpOnly = true;
      options.Cookie.IsEssential = true;
   });
   // other needed initializations
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
   app.UseSession();
   // other configurations
}

For more detailed samples check the Microsoft samples in GitHub.

Even with this it will might not work for you because you use SignalR. The documentation states the following:

Session isn't supported in SignalR apps because a SignalR Hub may execute independent of an HTTP context. For example, this can occur when a long polling request is held open by a hub beyond the lifetime of the request's HTTP context.

like image 194
AlesD Avatar answered Oct 10 '22 19:10

AlesD