problem with creating my Context on migration adding - c#

I have been working on project for some time now and I was able to add migrations without problem but week or two ago i transitioned from using onconfiguring optionsbuilder.useSqlServer to connect to sql server from my context class to using services from Startup class to connect to database
When I try to run add-migration i get this error
Unable to create an object of type 'mojDbContext'. For the different patterns supported at design time
Program class
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
startup class
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<mojDbContext>(options=> options.UseSqlServer(Configuration.GetConnectionString("ererer")));
services.AddControllersWithViews();
services.AddMvc();
services.AddDistributedMemoryCache();
services.AddSession();
}
// 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.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
my context class with removed dbset properties to keep code smaller
public class mojDbContext : DbContext
{
public mojDbContext(DbContextOptions<mojDbContext> options)
: base(options)
{
}
}
when i run add-migration -verbose i get this
https://i.stack.imgur.com/Rn7Op.png

Related

asp.net core none of the controllers are initialized

I have an ASP.NET project and everything is returning a 404, here's my startup code
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();
}
// 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");
app.UseStaticFiles();
app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapGet("/debug/routes", async ctx =>
{
await ctx.Response.WriteAsync(string.Join(", ", endpoints.DataSources.SelectMany(x => x.Endpoints)));
});
});
}
}
here's a sample controller:
public class Home : Controller
{
private readonly DatabaseContext _databaseContext;
public Home(DatabaseContext databaseContext)
{
Console.WriteLine($"Initialized home controller"); // This doesn't get called at all.
_databaseContext = databaseContext;
_databaseContext.Database.EnsureCreated();
}
[HttpGet("/home")]
public IActionResult Index()
{
ViewData["Products"] = _databaseContext.Products.ToList();
return View();
}
.....
and whenever I launch the server it I would go to /home and it would return 404, I also go to /debug/routes and it would show only the 2 endpoints inside the UseEndpoints function but never the controller classes I made
Try registering you db context in service as below. You could be getting error due to dependency of DatabaseContext on your HomeController would not be able to resolve.
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add below line
services.AddDbContext<DatabaseContext>(options => options.UseSqlServer(connectionString));
services.AddControllersWithViews();
}
In the Configure(IApplicationBuilder app, IWebHostEnvironment env) method of the Startup class you need something like: app.MapControllers();
I think you controllers are registered to DI throught the call services.AddControllersWithViews(); but there is no middleware registration to invoke your controllers, wich should be done in the Configure method.

Connection string keyword 'server' is not supported DB Migration

I'm getting this error when I try the migration commands :
Add-Migration AddAuthentication
Update-Database
I've added all the proper nugget packages so I don't know where the error stems from.
Here is my 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.AddRazorPages();
services.AddDbContext<AuthDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("AuthConnectionString")));
services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<AuthDbContext>();
}
// 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.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
And this is my Model :
public class AuthDbContext : IdentityDbContext
{
public AuthDbContext(DbContextOptions<AuthDbContext> options) : base(options)
{
}
And here is the connection string :
"ConnectionStrings": {
"AuthConnectionString": "Server=.;Database=AspNetAuth;Trusted_Connection=True"
}
}
Thank you for your time !
I use this connection string for local sql server
"Data Source=localhost;Initial Catalog=xxxx;Integrated Security=SSPI;Persist Security Info=True;"

Autofac configuration for ASP.Net Core 3.1 not working

I am trying to use Autofac with ASP.Net Core 3.1 but I am getting an exception which does not make sense.
I am getting the following exception:
Autofac.Core.Activators.Reflection.NoConstructorsFoundException: 'No accessible constructors were found for the type 'Microsoft.AspNetCore.Mvc.ModelBinding.CompositeBindingSource'.'
I think the issue might be because of the order of services registered but I can't figure out what I am doing wrong. My configuration is as follows:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Startup.cs class
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public ILifetimeScope AutofacContainer { get; private set; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<EShopDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DBConnection")));
services.AddSwaggerGen();
services.AddOptions();
}
public void ConfigureContainer(ContainerBuilder containerBuilder)
{
containerBuilder.RegisterModule(new AutofacModule());
}
// 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();
this.AutofacContainer = app.ApplicationServices.GetAutofacRoot();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "eShop");
c.RoutePrefix = string.Empty;
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
AutofacModule.cs class
public class AutofacModule : Module
{
protected override void Load(ContainerBuilder builder)
{
// scan all assemblies in current application domain and resolve them on convention
builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.AsImplementedInterfaces();
}
}
What am I missing?
I was able to find the problem with the help of examples code...
The problem for me was in the AutofacModule.cs class. I was scanning the assembly incorrectly. Here is the working code.
public class AutofacModule : Module
{
protected override void Load(ContainerBuilder builder)
{
// scan all assemblies in current application domain and resolve them on convention
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.AsImplementedInterfaces();
}
}
Autofac has examples of projects in Github and I found out that their documentation was different from their example code. This is the link of the ASP.Net Core 3.1 Example. for anyone who wants to see the configuration.

.Net Core Multiple Startups files and service implementations for different api versioning

I want two versions of api gateway (1.0 and 2.0) in Net Core 3.1 . Additionally, I have a cache and permissions service. Is it possible for version 1.0 to have a different permissions service implementation than for version 2.0? Is it possible to have two different Startup files?
As far as I know, we could have Startup class conventions and Startup method conventions.
Startup class conventions:
The app can define multiple Startup classes for different environments. The appropriate Startup class is selected at runtime. The class whose name suffix matches the current environment is prioritized. If a matching Startup{EnvironmentName} class isn't found, the Startup class is used.
That means you could have multiple startup.cs like StartupDevelopment,StartupProduction, Startup. If your host application's server environment variable "ASPNETCORE_ENVIRONMENT" has been set to the "Development", it will use StartupDevelopment. If there is no startup.cs match the ASPNETCORE_ENVIRONMENT, it will use default Startup.cs.
More details about how to set the environment variable , you could refer to this article.
Codes like below:
public class StartupDevelopment
{
public StartupDevelopment(IConfiguration configuration)
{
Configuration = configuration;
Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.Name);
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app)
{
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
public class StartupProduction
{
public StartupProduction(IConfiguration configuration)
{
Configuration = configuration;
Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.Name);
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app)
{
app.UseExceptionHandler("/Error");
app.UseHsts();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
Console.WriteLine(MethodBase.GetCurrentMethod().DeclaringType.Name);
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
Your best bet is to register two different service implementations, with two different interface types.
interface IPermissions {}
interface IPermissionsV2 : IPermissions {}
class PermissionsV1 : IPermissions {}
class PermissionsV2 : IPermissionsV2 {}
public class APIV1{
public APIV1(IPermissions ...){}
}
public class APIV2{
public APIV2(IPermissionsV2 ...){}
}
// etc
Though you could use a proxy service to locate the real service. This feels like an anti-pattern that I shouldn't recommend;
interface IPermissions {}
interface IPermissions<T>:IPermissions {}
public class PermissionsV1 : IPermissions {}
public class PermissionsV2 : IPermissions {}
public class PermissionsProxy : IPermissions<T>{
private IPermissions implementation;
public PermissionsProxy (IServiceProvider provider){
if (typeof(T) ... )
implementation = provider.GetService<PermissionsV1>();
// etc
}
public void Method() => implementation.Method();
}
public class APIV1{
public APIV1(IPermissions<APIV1> ...){}
}
public class APIV2{
public APIV2(IPermissions<APIV2> ...){}
}
Or configure multiple middleware pipelines with different services. But that feels over-complicated.

More than one DbContext named 'NewProject.Models.DbContext' was found Specify which one to use by providing its fully qualified name using exact case

I was developing a Web-App with Asp.Net Core 2.1 . After I added the new identity with scaffolder it generated me these codes:
Code generated in IdentityStartup.cs
[assembly:HostingStartup(typeof(ShareAndCare.Areas.Identity.IdentityHostingStartup))]
namespace ShareAndCare.Areas.Identity
{
public class IdentityHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) => {
services.AddDbContext<ShareAndCareContext>(options =>
options.UseLazyLoadingProxies().UseSqlServer(
context.Configuration.GetConnectionString("ShareAndCareContextConnection")));
services.AddIdentity<ShareAndCareUser, IdentityRole>()
.AddEntityFrameworkStores<ShareAndCareContext>()
.AddDefaultTokenProviders();
services.AddSingleton<IEmailSender, EmailSender>();
});
}
}
}
Code generated in Startup.cs
namespace ShareAndCare
{
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);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
This was working fine until I wanted to scaffold a model with controller and views using EF. When set up everything and click ok I was getting an error saying : More than one DbContext named 'ShareAndCare.Models.ShareAndCareContext' was found. Specify which one to use by providing its fully qualified name using its exact case. I checked all the folders and namespaces but there was no problem there, there was only one context with that name. So what was the problem ?
I'm leaving that question and answer here so people don't go crazy looking for all possible solutions manually like I did. I found out that adding the context in the Configure method of IdentityHostingStartup.cs was causing the problem. I changed the place where I added the context to the Configure method of Startup.cs and it was working just fine.
namespace ShareAndCare
{
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<ShareAndCareContext>(options =>
options.UseLazyLoadingProxies().UseSqlServer(
Configuration.GetConnectionString("ShareAndCareContextConnection")));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider serviceProvider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
I just deleted the 2 files:
Areas/Identity/Data/APNameIdentityDbContext.cs and
Areas/Identity/IdentityHostingStartup.cs
This fixed the error!
In my Case I was adding
services.AddDbContext<DBContext>
but instead my DBContext name was
ApplicationDBContext.
Changed my Name in Startup.cs and it worked
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<ApplicationDBContext>(options => options.UseSqlServer(Configuration["Data:ConnectionStrings:DefaultConnection"]));
}
Hope this helps someone :)

Categories