When trying to register a database context in startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(option => option.EnableEndpointRouting = false);
services.AddDbContext<PostDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("PostDbContext")));
}
I get error
The name "Configuration" does not exist in the current context.
All code examples are taken from the official Microsoft documentation.
Tutorials -> MVC -> Get started -> Add model.
ASP.NET Core version: 3.1
How fix it?
I have not defined a configuration.
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
This problem occurs because you have not defined Configuration which is an instance of IConfiguration interface like this-
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
Here Configuration is important to define which checks configuration details.
For Ex.-Configuration.GetConnectionString("Your Connection String") checks the connection string from appsettings.json file to get or set data in database.
Related
I have a .net Core application and I've been attempting to read from my local instance of SQL Server (2014) with Windows Authentication and continue to run into a repeat error about my connection string. I've been reviewing the MSDN docs as well as connectionstrings.com and thought I had everything configured correctly.
This is my error:
"System.ArgumentException: 'Format of the initialization string does
not conform to specification starting at index 0.'"
Which I take to mean the very start of my connection string.
I have read the other posts related to this exact issue but haven't been able to use them to find a solution.
Here is what I attempt when the error occurs:
public class HomeController : Controller
{
private ModelContext _context;
public HomeController()
{}
public IActionResult Index()
{
var viewModel = new HomeViewModel();
var optionsBuilder = new DbContextOptionsBuilder<ModelContext>();
optionsBuilder.UseSqlServer("DefaultConnection");
using (_context = new ModelContext(optionsBuilder.Options))
{
>>>>>> viewModel.List = _context.TableName.ToList(); <<<<<<<<
I have the following in my "appsettings.json" file:
"ConnectionStrings": {
"DefaultConnection": "Server=MyComputerName; Database=DBName; IntegratedSecurity=SSPI;"
},
In my "ModelContext.cs" file
public class ModelContext : DbContext
{
public ModelContext(DbContextOptions<ModelContext> options)
:base(options)
{ }
[<Table Properties>]
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("DefaultConnection");
}
And "Startup.cs" file:
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 => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddDbContext<ModelContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
Thanks for taking a look!
After much contemplation and re-review of the MS Documents site for EF Core DbContext, I found that I was attempting to implement ALL 3 methods of DbContext configuration: Constructor Argument, OnConfiguring, and dependency injection.
Decided to go with OnConfiguring to get the app moving.
I've followed several methods on StackOverflow to fix my issue, none with a result:
My DefaultConnection-string is in my AppSettings.json. To retrieve info I am reading to use the IConfiguration from my startup.cs. The constructor of my MsSQL-context is still asking for this IConfiguration. Note: I'm using a repository pattern.
startup.cs:
public Startup(IConfiguration configuration)
{
this.Configuration = configuration;
}
public IConfiguration Configuration { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConfiguration>(Configuration);
I've added the Singleton in my startup after a suggestion. With or without this the constructor of MsSQLContext is still requesting this as a variable to be passed. Leaving the constructor without this gives me the error: Connectionstring not initialized.
AdminMsSQLContext:
private readonly string _connectionString;
public MSSQLAdminContext(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("DefaultConnection");
}
Injecting IConfiguration is actually an anti-pattern, anyways. What you should be doing is supplying an action to your scope registration and change your MSSQLAdminContext class to accept just the connection string in its constructor:
public MSSQLAdminContext(string connectionString)
{
_connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
}
Then:
services.AddScoped(_ =>
new MSSQLAdminContext(Configuration.GetConnectionString("DefaultConnection)));
Your repo should not have knowledge of something like your configuration. If it needs a connection string, then it should take the connection string, and that is all.
I believe the issue you are having is that you have not registered the MSSQLAdminContext with the DI container. Because of this the DI engine does not know to inject the IConfiguration into the class. In your start up you will register this class however you need, I tend to use scoped for these types of classes you may use in multiple places. So something like this.
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<MSSQLAdminContext>();
services.AddSingleton<IConfiguration>(Configuration);
}
I Created an asp.net core project And I selected UseIndiviualUserAccount As My AutenticationType,
After preparing project by visual studio i got some prebuilt class and controller,
Obviously i got migration folder and its config since i dont want to use defulat structure of asp.net core ,i deleted the migration folder and i created a new class library and i Rename it to MyProject.Core.
in MyProject.Core Class Library i create my db models and dbContext classes,so i need to run the add-migration "init" command for creating my database so i did but i got below error,
Note : i am running the add migration command in Myproject.Core in PMC !!
Unable to create an object of type 'ApplicationDbContext'. Add an implementation of 'IDesignTimeDbContextFactory' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
how can i fix this error, i read some article in current site and the other website but i cant fix my problem.
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
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.AddTransient<IUnitOfWork, UnitOfWork>();
services.AddTransient<IProvinceRepository, ProvinceRepository>();
services.AddTransient<IBrandRepository, BrandRepository>();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
// Add application services.
services.AddTransient<IEmailSender, EmailSender>();
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseBrowserLink();
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser,ApplicationRole,string>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options): base(options)
{
}
static ApplicationDbContext()
{
// Set the database intializer which is run once during application start
// This seeds the database with admin user credentials and admin role
// Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
}
This can happen when EF don't know where the entry point to your application is. You do not need to implement IDesignTimeDbContextFactory if you're using BuildWebHost.
First of all, make sure that you are running your migration from the project containing the migrations.
Eg... if you're using Package Manager Console:
cd .\MyProject.Core
Then run your migration using startup-project and point it to the project with BuildWebHost.
dotnet ef --startup-project ../MyProject.Web/ migrations add Initial
Otherwise EF will not know where your implementation is.
Here is my asp.net core project structure
1- ASP.NET CORE Web API (contains aspsettings.json)
"ConnectionStrings": {
"DefaultConnection": "Server=(local)\\SQLEXPRESS;Database=testdb;Trusted_Connection=True;"
}
2-SERVICES Project (Web API Call method from Services Project)
3-REPOSITORY Project (Services call method from Repository Project and Repository Project include the DATA Project where all the models are)
4-DATA Project where it's contain all the model with code first
public class TtEntities : DbContext
{
public virtual DbSet<RoomMessage> RoomMessage { get; set; }
public virtual DbSet<UserRoom> UserRoom { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(#"Server=(local)\SQLEXPRESS;Database=testdb;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
....
As you can see, I hardcoded the connection on the method OnConfiguring which is not the best practice for sure.
Is there a way to pass the connection string from the configuration file of the Web API Project?
Is update database command will still work if we pass the connection from the file aspsettings.json from web api project ?
Thanks a lot
A simple solution is like this:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
}
Consider how DefaultConnection is used in line 13. Also a sample appsettings is like as follow:
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-WebApplication5;"
}
}
DI solves this problem perfectly and .NET Core 2.0 has Microsoft DI thats provides clearly experience with DI.
oh, lets starts(i think that DATA Project and REPOSITORY Project should be one)
from REPOSITORY Project
change your REPOSITORYClass to
public class REPOSITORYClass
{
private readonly TtEntities _db;
public REPOSITORYClass (TtEntities db){
_db = db;
}
//some your staff of REPOSITORYClass thats uses _db
}
now go to SERVICES Project
lets change some service that uses REPOSITORYClass
public class SomeService
{
private readonly REPOSITORYClass _repo;
public SomeService (REPOSITORYClass repo){
_repo = repo;
}
//other staff of SomeService thats uses _repo
}
after that go to ASP.NET CORE Web API startup file and add to
public void ConfigureServices
// Get connection of your repo
string connection = Configuration.GetConnectionString("DefaultConnection");
// add TtEntities as service
services.AddDbContext<TtEntities>(options =>
options.UseSqlServer(connection));
//add your repo
services.AddTransient<REPOSITORYClass>();
//add your service
services.AddTransient<SomeService>();
now go to the contoller thats uses your SomeService
public class SomeController: Controller
{
private readonly SomeService _someService;
public SomeController(SomeService someService){
_someService = someService;
}
//And use whatever your wants from your service that injected with deps of repo and injected db entity with connection
public string SomeMethod()
{
return _someService.SomeMethod();
}
}
And use whatever your wants from your service that injected with deps of repo and injected db entity with connection
thats all
PS also recommend to read this Introduction to Dependency Injection in ASP.NET Core
I am trying to use custom configuration for a web app that I intent to host on Azure. The configuration should be overridable by Environment variables so that I can change it on Azure portal.
I tried with following code but it does not work - details below
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
var builder = new ConfigurationBuilder()
.AddJsonFile("config.json", optional:true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<AppSettings>(Configuration);
}
In the controller,
public class HomeController : Controller
{
private IOptions<AppSettings> Configuration;
public HomeController(IOptions<AppSettings> configuration)
{
Configuration = configuration;
}
public async Task<IActionResult> Index()
{
string location = Configuration.Value.Location;
...
}
The default config.json file looks like,
{
"AppSettings": {
"Location" : "Singapore"
}
}
On Azure Portal, under app settings I have assigned value to AppSettings:Location to US and I am expecting US value in the controller.
Locally, in ConfigureServices I can see the value as Singapore but in the controller action Index it is null.
Am I missing something here?
When you are reading the config.json, you need to load the section that you want to read, you need to update your code as follow:
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
}