System.ArgumentNullException: 'Value cannot be null. (Parameter 'connectionString')' - asp.net-mvc

This is the appsetting.json file
{
"Connection Strings": {
"EmployeeDBConnection": "server=(localhost)\\SQLEXPRESS ; database=EmployeeDB; Trusted_Connection =true"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"MyKey": "Value of MYKey from appsettings.json"
}
This is the startup.cs file
namespace EmployeeManagement
{
public class Startup
{
private IConfiguration _config;
public Startup(IConfiguration config)
{
_config = config;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IEmployeeRepository, SQLEmployeeRepository>();
services.AddControllersWithViews();
services.AddDbContextPool<AppDbContext>(options => options.UseSqlServer(_config.GetConnectionString("EmployeeDBConnection")));
}
// 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.UseStaticFiles();
app.UseMvcWithDefaultRoute();
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World");
});
}
}
}
I have checked that "Connection Strings" has s in the end,
Changed the placement of the connection strings in the appsetting.json file
Instead of just writing the name of the connection string in Configuration.GetConnectionString() in Startup.cs, I put the entire ConnectionString there
I am still having this error.

Your key "Connection Strings" contains space. Change to "ConnectionStrings" for the intended behavior.

"Connection Strings" does not match your parameter "connectionStrings". You need to change that in appsettings.cs. It could also need to be "connectionString" instead, I am a bit confused by your wording. Regardless, your program is looking for "connectionString", not "Connection Strings".

Related

ASP.NET core Azure AD authorization problem (chrome doesn't save cookies and makes loop requests)

I'm trying to add azure AD to my project and use this tutorial as example.
With localhost all works fine, but after deploying a have such problem as loop redirects from chrome (version 91) Also i get this problem using last version of opera and edge. While doing the same in safari and Firefox i didn't get any problems.
I think it might be a problem with samesite cookies, but i have already tried every one variant (none,lax,unspecified, strict). Also i noticed, that in Firefox in response Cookies i recieve "AspNetCore.Cookies and in Chome i'm not. but in chrome it's only these one
Is anyone can help me with that problem?
My StartUp file
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.Unspecified;
options.HandleSameSiteCookieCompatibility();
});
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddMicrosoftIdentityWebAppAuthentication(Configuration);
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters.RoleClaimType = "roles";
});
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
appsettings.json
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "11111111-1111-1111-1111-111111111111",
"ClientId": "11111111-1111-1111-1111-111111111112",
"CallbackPath": "/signin-oidc"
},
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*"
}
Here is a fix (it could be not the best, but it works well for me).
MDN spec says: "The warning appears because any cookie that requests SameSite=None but is not marked Secure will be rejected." That was my problem with browsers run over Chromium engine (Chrome/Opera/Edge). The default value was CookieSecurePolicy.SameAsRequest i changed it to CookieSecurePolicy.Always :
services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
options.CorrelationCookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always;
options.NonceCookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always;
});
Some screenshot of warning in chrome:
before
after

Not all Information is appearing in Kibana (Serilog)

When I run my AspNetCore V5 app I only see logging appear in Kibana up to the point I call CreateHostBuilder(args).
So, in Kibana I see
Step 1
and
Starting app
But nothing after that. Even if I add Log.Information("Requested data"); in a controller method that is being executed, I don't see it.
appsettings.json
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Information",
"System": "Warning"
}
}
},
"ElasticConfiguration": {
"Uri": "http://localhost:9200"
},
"AllowedHosts": "*"
}
Program.cs
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Sinks.Elasticsearch;
using System;
using System.Reflection;
namespace BlazorElkSerilogTest.Server
{
public class Program
{
public static void Main(string[] args)
{
//configure logging first
ConfigureLogging();
Log.Information("Step {step}", 1);
IHostBuilder hostBuilder = CreateHostBuilder(args);
Log.Information("Step {step}", 2);
IHost host = hostBuilder.Build();
Log.Information("Step {step}", 3);
host.Run();
}
static void ConfigureLogging()
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",
optional: true)
.Build();
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.WriteTo.Debug()
.WriteTo.Console()
.WriteTo.Elasticsearch(ConfigureElasticSink(configuration, environment))
.Enrich.WithProperty("Environment", environment)
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
static ElasticsearchSinkOptions ConfigureElasticSink(IConfigurationRoot configuration, string environment)
{
return new ElasticsearchSinkOptions(new Uri(configuration["ElasticConfiguration:Uri"]))
{
AutoRegisterTemplate = true,
IndexFormat = $"{Assembly.GetExecutingAssembly().GetName().Name.ToLower().Replace(".", "-")}-{environment?.ToLower().Replace(".", "-")}-{DateTime.UtcNow:yyyy-MM}"
};
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
try
{
Log.Information("Starting app");
return Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.ConfigureAppConfiguration(configuration =>
{
configuration.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
configuration.AddJsonFile(
$"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json",
optional: true);
})
.UseSerilog();
}
catch (Exception e)
{
Log.Fatal(e, "Application startup failed");
throw;
}
finally
{
Log.CloseAndFlush();
}
}
}
}
The try/catch/finally should wrap the code in Main, not CreateHostBuilder - otherwise the logger is closed before the app runs!

ASP.Net Core Identity Pages throws 404 error after deploying to server but work fine hosting in local IIS

Once after hosting the project both in local IIS and in server, I found that in server all the identity related pages throws 404 error, whereas in local IIS it works fine. All the other pages apart from Identity Pages are accessible. My StartUp class looks like this:
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.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddSingleton<IFileProvider>(
new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")));
var connectionString = this.Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext<ApplicationDbContext>(options =>
{
options.UseSqlServer(connectionString);
options.UseLazyLoadingProxies(true);
});
//services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddDefaultIdentity<XonetPlus_V3.Entities.Domain.User>(options => options.SignIn.RequireConfirmedAccount = false)
.AddRoles<IdentityRole>().AddDefaultUI()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(#"c:\shared-auth-ticket-keys\"))
.SetApplicationName("SharedCookieApp");
services.ConfigureApplicationCookie(options => {
options.Cookie.Name = ".AspNet.SharedCookie";
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
services.AddTransient<IRepositoryWrapper, RepositoryWrapper>();
services.AddScoped<IEmailSender, EmailSender>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, UserManager<User> userManager, RoleManager<IdentityRole> roleManager)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRouting();
app.UseAuthentication();
IdentityDataInitializer.SeedData(userManager, roleManager);
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute("default", "{controller=admindashboard}/{action=Index}/{id?}");
// endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute("queryParams", "{controller=admindashboard}/{action=Index}/{param}/{id}");
endpoints.MapControllerRoute("areas", "{area:exists}/{controller=admindashboard}/{action=Index}");
endpoints.MapRazorPages();
});
}
}

Redis Cache not working with Asp.net core

I try to implement redis cache in Asp.Net Core Application but its not Set any value in HttpContext.Session and not even return any value.This is my startup.cs file.
public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedRedisCache(options =>
{
options.InstanceName = Configuration.GetValue<string>("redis:name");
options.Configuration = Configuration.GetValue<string>("redis:host");
});
services.AddSession(o=> { o.IdleTimeout = TimeSpan.FromMinutes(5); });
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment 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.UseSession();
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Appsetting.json
"redis": {
"host": "redis-17930.c1.ap-southeast-1-1.ec2.cloud.redislabs.com",
"port": 17930,
"name": "Astroyogi"
},
HomeController.cs
public IActionResult Index()
{
var helloRedis = Encoding.UTF8.GetBytes("Hello Redis");
HttpContext.Session.Set("hellokey", helloRedis);
var getHello = default(byte[]);
HttpContext.Session.TryGetValue("hellokey", out getHello);
ViewData["Hello"] = Encoding.UTF8.GetString(getHello);
return View();
}
and the lib which i installed-
Microsoft.Extensions.Caching.Redis
Microsoft.AspNetCore.Session
and its will not set any value in session.
Please help me where i am stucking.
You cannot both set and get the value you just set in the Session in the same request. Session requires a cookie to be set, which will only happen after you return the response. On the next request, you should be able to access your value fine.

ASP.Net Core MVC Dependency Injection not working

I am trying to inject a interface into to my HomeController and I am getting this error:
InvalidOperationException: Unable to resolve service for type 'Microsoft.Extensions.Configuration.IConfiguration' while attempting to activate
My Startup class is as follows:
public Startup(IApplicationEnvironment appEnv)
{
var builder = new ConfigurationBuilder()
.SetBasePath(appEnv.ApplicationBasePath)
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json");
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<ApplicationDbContext>(options => options
.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
services.AddSingleton(provider => Configuration);
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
}
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseApplicationInsightsRequestTelemetry();
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
try
{
using (var serviceScope = app.ApplicationServices
.GetRequiredService<IServiceScopeFactory>()
.CreateScope())
{
serviceScope.ServiceProvider
.GetService<ApplicationDbContext>()
.Database.Migrate();
}
}
catch { }
}
app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear());
app.UseApplicationInsightsExceptionTelemetry();
app.UseStaticFiles();
app.UseIdentity();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
app.Run((async (context) =>
{
await context.Response.WriteAsync("Error");
}));
}
and my HomeController constructor is:
public HomeController(IConfiguration configuration, IEmailSender mailService)
{
_mailService = mailService;
_to = configuration["emailAddress.Support"];
}
Please tell me where I am mistaken.
Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider, ISet`1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
Try injecting it as an IConfigurationRoot instead of IConfiguration:
public HomeController(IConfigurationRoot configuration
, IEmailSender mailService)
{
_mailService = mailService;
_to = configuration["emailAddress.Support"];
}
In this case, the line
services.AddSingleton(provider => Configuration);
is equivalent to
services.AddSingleton<IConfigurationRoot>(provider => Configuration);
because the Configuration property on the class is declared as such, and injection will be done by matching whatever type it was registered as. We can replicate this pretty easily, which might make it clearer:
public interface IParent { }
public interface IChild : IParent { }
public class ConfigurationTester : IChild { }
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
IChild example = new ConfigurationTester();
services.AddSingleton(provider => example);
}
public class HomeController : Controller
{
public HomeController(IParent configuration)
{
// this will blow up
}
}
However
As stephen.vakil mentioned in the comments, it would be better to load your configuration file into a class, and then inject that class into controllers as needed. That would look something like this:
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
You can grab these configurations with the IOptions interface:
public HomeController(IOptions<AppSettings> appSettings)
In Core 2.0 it's recommended to use IConfiguration instead of IConfigurationRoot
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
from https://learn.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/#add-configuration-providers
When moving a project from .Net Core 1.x to 2.0, change all IConfigurationRoot to IConfiguration

Resources