System.InvalidOperationException when using HttpContext.Session with use.Session(); set - c#

I am developing a .NET Core 3.0 application using Razor pages for a project in my studies. The application is going to use a login feature and I am want to use sessions to send data and verify what user is logged in.
For this I have decided to use HttpContext.Session to get and set strings during post.
When I use the line: HttpContext.Session.SetString("username", "test");
I get the error: System.InvalidOperationException: 'Session has not been configured for this application or request.'
After some extensive googling and using a Microsoft doc I cannot seem to find a solution. Everywhere I get the answer that I need to include services.AddSession and app.UseSession(); in my Startup.cs file which I do, These are all added before the 'UseMvc();' lines.
I have run out of options and my software teacher does not want to give me any help aside from "are you using the correct version" which I think I do according to the Microsoft docs.
What am I missing that causes this error? How can I get sessions to work? Am I implementing it wrong?
Below is my Startup.cs class:
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.AddDistributedMemoryCache();
services.AddRazorPages();
services.AddSession(options =>
{
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
options.IdleTimeout = TimeSpan.FromSeconds(10);
});
services.AddMvc(option => option.EnableEndpointRouting = false);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSession();
app.UseMvc();
}
}
Notable is when I use app.UseHttpContextItemsMiddleware(); between
app.UseSession(); and app.UseMvc(); I get an Intellisense error that says IApplicationBuilder does not have this method. In the Microsoft docs it is show that this string is included in Startup.cs.

Everywhere I get the answer that I need to include services.AddSession and app.UseSession(); in my Startup.cs file which I do, These are all added before the 'UseMvc();' lines.
Yes, you're right. However, either invoke UseMvc() or invoke UseRouting()+ UseEndpoints(), but don't invoke them both. As of ASP.NET 3.0, I would suggest you should use UseRouting()+ UseEndpoints() instead of the UseMvc().
In your original codes, the UseEndpoints() is triggered before UseSession() which makes the MVC/Razor Page execute before UseSession(). To fix that issue, change your code as below:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseHttpsRedirection();
app.UseStaticFiles();
// put UseSession before the line where you want to get the session.
// at least, you should put it before `app.UseEndpoints(...)`
app.UseSession();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
// if you need mvc, don't forget to
// add `services.AddControllersWithViews`
// and add this line
endpoints.MapControllerRoute(
name: "default-controller",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSession();
app.UseMvc();
}

Related

Calling class function from program.cs at runtimes in .net 6 [duplicate]

This question already has an answer here:
.NET 5 to .NET 6 Migration Startup and Configure methodology in Minimal Hosting
(1 answer)
Closed last year.
In previous core version, if there is need to pass dependency while calling any function i used to pass parameter in configure method and use same value to pass as parameter while calling function.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
UserManager<IdentityUser> usermanager, RoleManager<IdentityRole rolemanager)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
SeedData.Seed(userManager, roleManager);
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
But in .Net 6 same flow cannot be applied due to only program.cs file. I tried to call function from program.cs file but i get : 'Cannot resolve scoped service 'Microsoft.AspNetCore.Identity.UserManager`1[Microsoft.AspNetCore.Identity.IdentityUser]' from root provider.'
Program.cs File
using LeaveManagement;
using LeaveManagement.Data;
using LeaveManagement.Interfaces;
using LeaveManagement.Mapper;
using LeaveManagement.Repositories;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddAutoMapper(typeof(Maps));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddControllersWithViews().AddRazorRuntimeCompilation();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
var userManager = app.Services.GetRequiredService<UserManager<IdentityUser>>();
var roleManager = app.Services.GetRequiredService<RoleManager<IdentityRole>>();
SeedData.Seed(userManager, roleManager);
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();
app.Run();
I find the above solution working for some case but it is not working for me.
If you really want to get the object
var usermanager = services.BuildServiceProvider().GetService<UserManager<IdentityUser>>();
It can help (of cause, you only call it AFTER adding the services). But you can consider another way to achieve your work. Because by calling BuildServiceProvider, the framework can't guarantee the singleton scope.

Loading Static Files from Controller ASP Net Core MVC

I have a puzzling problem, my application loads static files from controller folder, but in default route it loads normally
Example:
https://localhost:44369/plugins/bootstrap/js/bootstrap.bundle.min.js (in normal situation) (needs to be work)
In my situation
https://localhost:44369/Order/plugins/bootstrap/js/bootstrap.bundle.min.js
It wants to load from static files from controller folder which does not exist.
I use Admin LTE 3 Template (maybe the template has some issues?)
Thank you :)
Startup.cs
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.AddHttpClient();
services.AddAutoMapper(typeof(Startup));
services.AddControllersWithViews().AddRazorRuntimeCompilation();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<ICustomerService, CustomerManager>();
services.AddSingleton<ICustomerDal, CustomerDal>();
services.AddSingleton<IInformationResourcesService, InformationResourcesManager>();
services.AddSingleton<IInformationResources, EFInformationResourcesDAL>();
services.AddSingleton<INewOrderService, NewOrderManager>();
services.AddSingleton<INewOrderService, NewOrderManager>();
services.AddSingleton<INewOrderDal, EfNewOrderDalL>();
services.AddSingleton<ICityDal, EFCityDal>();
services.AddSingleton<ICityService, CityManager>();
services.AddSingleton<IDisctrictDal, EFDistrictDal>();
services.AddSingleton<IDistrictService, DistrictManager>();
services.AddSingleton<IVillageDal, EFVillageDal>();
services.AddSingleton<IVillageService, VillageManager>();
services.AddSingleton<IStreetDal, EFStreetDal>();
services.AddSingleton<IStreetService, StreetManager>();
services.AddSingleton<ICustomerAdressService, CustomerAdressManager>();
services.AddSingleton<ICustomerAdressDal, EFCustomerAdressDal>();
//services.AddCors(options =>
//{
// options.AddPolicy("CorsPolicy",
// builder => builder
// .AllowAnyMethod()
// .AllowCredentials()
// .SetIsOriginAllowed((host) => true)
// .AllowAnyHeader());
//});
//services.AddDependencyResolvers(new ICoreModule[] {
// new CoreModule()
//});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
//app.UseCors("CorsPolicy");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Customer}/{action=Index}/{id?}");
});
}
}
Can you specify how you are adding the script to your page.
I am using a template as well and my scripts are located in wwwroot/vendors folder
this is my script tag.
<script src="~/vendors/jquery/dist/jquery.min.js" type="text/javascript"></script>

React asp.net SPA calling API on same app service

I have one solution that includes two projects:
Foo - this an asp.net React site
Bar - this is an asp.net API, which the Foo projects calls
I have deployed both of these projects to one Azure app service using virtual directories.
Virtual Directory Setup
When the Foo app makes a call to https://azureFooapp.com/api/getData all that is returned is the index.html file from the Foo project. Instead of actually calling the endpoint located in the Bar API project.
If I remove the Foo project project from the App Service I am able to hit the endpoint https://azureFooapp.com/api/getData successfully.
Foo Startup.cs
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.AddControllersWithViews();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
services.AddControllers()
.AddNewtonsoftJson();
services.AddMvc().AddNewtonsoftJson(o =>
{
o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
}
}
Bar Startup.cs
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.Configure<ConnectionStrings>(Configuration.GetSection("ConnectionStrings"));
services.AddControllers();
services.AddControllersWithViews();
services.AddControllers()
.AddNewtonsoftJson();
services.AddMvc().AddNewtonsoftJson(o =>
{
o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin", builder =>
{
builder.WithOrigins("https://localhost").AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
});
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("AllowSpecificOrigin");
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
Can anyone please help get this working? If anymore information is needed please let me know
I suggest you put the api project under wwwroot and the react project in the virtual directory.
Like :
Virtual path Physical Path Type
/ site\wwwroot Application
/pages site\wwwroot\react_folder Application
Suggestions
Why is it not recommended to put nodejs projects, such as react, angular, and vue projects into the main application?
After a lot of testing, I found that when the main application is put into these three items, the virtual application will not take effect, and it can work normally if they are put into the virtual application.
(Not recommended) After the react project is compiled, if the content of the dist folder is released, the routing access of virtual applications is supported in iis, and this is not recommended.
I have now managed to resolve this issue by modifying the code in Foo Startup.cs with the below
app.MapWhen(x => !x.Request.Path.Value.ToLower().StartsWith("/api"), builder =>
{
builder.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
});
After this I restarted the App Service

AddCors is not working in asp.net 5.0. How do I enable it?

So my problem is that I tried to enable the CORS, followed the tutorial and it is still not working. My startup.cs looks like this (I include methods to which I tried enabling CORS). Any help would be appreciated:
ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options=>options.AddDefaultPolicy(builder=>builder.AllowAnyOrigin()));
services.AddControllers();
services.Add(new ServiceDescriptor(typeof(ApplicationDbContext),
new ApplicationDbContext(Configuration.GetConnectionString("DefaultConnection"))));
}
And then I try to use cors in the Configure method.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
I use the newest .NET core version.
Error specifically is:
Access to XMLHttpRequest at 'http://localhost:5000/api/cities' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
Thanks in advance.
Try to use this syntax and assign name to the policy
services.AddCors(o => o.AddPolicy("AllowAnyOrigins", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
.......
app.UseRouting();
app.UseCors("AllowAnyOrigins");
app.UseAuthorization();

Configure Strict Cors .Net Core 3.1

I have a public analytics web api (.Net Core 3.1) that captures basic analytics from my various web apps and sites (page views, etc). I'd very much like to configure cors in a more strict manner as I am well aware of the origins from where traffic should come. It's worth noting that I'm updating this application from .Net Core 2.2 to .Net Core 3.1.
I have the following method in my Startup.cs file
public void ConfigureServices(IServiceCollection services)
{
...
ConfigureCors(services);
}
private void ConfigureCors(IServiceCollection services)
{
// https://weblog.west-wind.com/posts/2016/Sep/26/ASPNET-Core-and-CORS-Gotchas
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.WithOrigins(AppConfiguration.CorsOrigins)
.AllowAnyMethod()
.AllowAnyHeader());
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers().RequireAuthorization();
});
}
AppConfiguration is a class I use to handle configurations and it grabs json values using the following:
public string[] CorsOrigins => _config["CorsOrigins"].Split(',');
In appsettings.Development.json, I have "CorsOrigins": "*"
I'd very much like to specify strict origins in the appsettings.Production.json and appsettings.Staging.json files.
E.g.
"CorsOrigins": "https://subdomain.example.com,https://www.example.com,https://example.com", but on deployment, I get a status of 502 whenever by websites/apps hit the various endpoints.
"CorsOrigins": "*" works on local so there can't be anything wrong with the Startup.cs file as far as I'm aware.
Update: "CorsOrigins": "*" actually does not work for the staging or production environments either. Now I'm even more confused. To be clear, this is a cors question. The following worked fine before upgrading to .Net Core 3.1:
private void ConfigureCors(IServiceCollection services)
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
}
Take care to place the UseCors at the right location. From the docs:
The call to UseCors must be placed after UseRouting, but before
UseAuthorization.
As noted in the comments, allowing "*" as origin isn't allowed with AllowCredentials.
Here's a working example of a CORS configuration from my ASPNET Core 3.1 project. It does the config in the Configure method instead of ConfigureServices, but same content:
// Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
// etc
}
public void Configure(IApplicationBuilder app)
{
// other configs
app.UseRouting();
// CORS configuration. Expects allowed origins as comma-separated list in config under 'Cors:AllowedOrigins'.
string configuredOrigins = Configuration["Cors:AllowedOrigins"] ?? throw new ArgumentNullException("Cors:AllowedOrigins");
string[] origins = configuredOrigins.Split(',', ';').Select(i => i.Trim()).ToArray();
app.UseCors(policy => policy
.WithOrigins(origins)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials() // Required by SignalR
.WithExposedHeaders(CONTINUATION_HEADER_KEY) // Allow use of custom header
.SetPreflightMaxAge(TimeSpan.FromSeconds(86400))); // Allow caching for 24 hours (depends on browser)
app.UseAuthentication();
app.UseAuthorization();
// other configs
}
Sorry this is a difficult question so there could be a number of reasons it doesnt work but Ive run into a similar issue and resolved its by altering the cors invocation in the Configure() function. The Configure() function is a gets called during runtime and acts as an http request pipeline so in some cases order of execution matters (https://learn.microsoft.com/en-us/aspnet/core/fundamentals/startup?view=aspnetcore-3.1#the-configure-method)
You could try the following:
Change the current:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseCors("CorsPolicy"); //Move this line
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers().RequireAuthorization();
});
}
To:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseCors("CorsPolicy"); // Here
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers().RequireAuthorization();
});
}
Hence the first operation in the http pipeline would be to validate cors.
I rate this is a fair bet as from your question it sounds like you dont get an app initialise error but rather a runtime client request time error.
I dont know for certain if this will solve the problem but maybe it helps!

Categories

Resources