How can I use an API controller as a service in an ASP.NET Core application? - asp.net-core

I'm new to entity framework and have built a working API with a controller that I'll call APIController. My aim is to use the API as a 'service' in my ASP.NET Core MVC app which is in the same project but a different solution by having an instance of the API controller in my MVC controller and using it for the View requests.
The issue is that doing it this way means I have two contexts: one for the database in the API 'TTContext', which is the main one used to actually edit the files and another in the MVC 'TraineeTrackerContext'which is required for userManager authentication because it needs to inherent IdentityDbContext (which can't be done in the API).
I've tried to introduce these contexts in the program.cs as below:
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using SpartaTraineeTrackerAPI.Models;
using SpartaTraineeTrackerAPI.Service;
using TraineeTrackerMVC.Data;
using SpartaTraineeTrackerAPI.Models;
using SpartaTraineeTrackerAPI.Service;
using TraineeTrackerMVC.Models;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext<TTContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDbContext<TraineeTrackerContext>(options => options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<User>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<TTContext>();
builder.Services.AddControllersWithViews();
builder.Services.AddScoped<ITrackerService, TrackerService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();
app.Run();
With the idea being that the TraineeTrackerContext has an instance of the TTContext attached like this:
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using TraineeTrackerMVC.Models;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using SpartaTraineeTrackerAPI.Models;
namespace TraineeTrackerMVC.Data;
public partial class TraineeTrackerContext : IdentityDbContext
{
public TraineeTrackerContext()
{
ttContext = new TTContext();
}
public TraineeTrackerContext(TTContext context)
{
ttContext = context;
}
/*
public TraineeTrackerContext(DbContextOptions<TraineeTrackerContext> options)
: base(options)
{
ttContext = new TTContext(options);
}
*/
public TTContext ttContext;
public virtual DbSet<Profile> Profiles { get; set; }
public virtual DbSet<Tracker> Trackers { get; set; }
public virtual DbSet<User> Users { get; set; }
public TraineeTrackerContext(DbSet<Tracker> trackers, DbSet<User> users, DbSet<Profile> profiles)
{
Trackers = trackers;
Users = users;
Profiles = profiles;
}
}
But running it throws two exceptions when doing builder.Build():
InvalidOperationException: Error while validating the service descriptor ServiceType
System.AggregateException: Unable to activate type Trainee TrackerContext
I've been trying to fix these myself but I'm very new to Entity Framework and this is one of the first applications I've made so I was hoping someone could help explain where I'm going wrong and perhaps how to do this correctly. I haven't found many resources online using the API as a service in this way, as others tend to use the HttpClient class. Any help would be appreciated.

Related

ASP.NET Core 6 OData Swagger UI always shows $count query

I created a new ASP.NET Core Web API project with Swagger and added an ODataController. The Swagger UI shows my Users route as expected, and it works. But the Swagger UI also unexpectedly shows Users/$count:
Why is $count there? Can I prevent it from appearing?
I'm using Microsoft.AspNetCore.OData 8.0.10 (the latest). I get the same results with Swashbuckle.AspNetCore 6.2.3 (the template default) and 6.3.1 (the latest).
My entire controller:
public class UsersController : ODataController
{
private readonly ErpContext _db;
public UsersController(ErpContext db)
{
_db = db;
}
[HttpGet]
public IActionResult Get()
{
return Ok(_db.Users);
}
}
My entire EDM:
public static class EntityDataModel
{
public static IEdmModel Build()
{
var builder = new ODataConventionModelBuilder();
builder.EntitySet<User>("Users");
return builder.GetEdmModel();
}
}
My entire startup, in case there's some order sensitivity or something:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContextFactory<ErpContext>(options =>
{
options.UseSqlServer(builder.Configuration["ConnectionStrings:DefaultConnection"]);
});
builder.Services
.AddControllers()
.AddOData(options =>
{
options.AddRouteComponents("odata", EntityDataModel.Build());
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Note that my controller action does not have [EnableQuery] and my ODataOptions does not have Count() or any other query. The unwanted $count query doesn't even work unless I add those.
I've reproduced the problem in a minimal project with an in-memory DB.

.Net Core 3 Identity register or login links not functional [duplicate]

After having a hard time getting my area to show with endpoint routing i managed to fix it in this self answered thread (albeit not in a very satisfactory way) : Issue after migrating from 2.2 to 3.0, default works but can't access area, is there anyway to debug the endpoint resolution?
However Identity UI doesn't show at all for me, i get redirected on challenge to the proper url but the page is blank. I have the identity UI nugget package added and, changing from mvc routing to endpoint routing, i didn't change anything that should break it.
I also don't seem to do much different than what the default project does and identity works there even if i add a route as i did in my hack.
As often the issue hides around the line and not on it i'm posting my whole startup file.
Regular (default) controllers work.
Admin area works (one of the page doesn't have authentication and i can access it)
Any other Admin area page redirect me to /Identity/Account/Login?ReturnUrl=%2Fback (expected behavior) but that page as well as any other /Identity page i tested is blank with no error while running in debug and with a debugger attached.
Any help is most appreciated, full startup bellow:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using FranceMontgolfieres.Models;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
namespace FranceMontgolfieres
{
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.AddSingleton<IConfiguration>(Configuration);
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
.AddDbContext<FMContext>(options => options
.UseLazyLoadingProxies(true)
.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services
.AddDefaultIdentity<IdentityUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<FMContext>();
services
.AddMemoryCache();
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = Configuration.GetConnectionString("SessionConnection");
options.SchemaName = "dbo";
options.TableName = "SessionCache";
});
services.AddHttpContextAccessor();
services
.AddSession(options => options.IdleTimeout = TimeSpan.FromMinutes(30));
services.AddControllersWithViews();
services.AddRazorPages();
}
// 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.UseDatabaseErrorPage();
}
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.UseRouting();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseSession();
app.UseEndpoints(endpoints =>
{
endpoints.MapAreaControllerRoute("Back", "Back", "back/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute("default","{controller=Home}/{action=Index}/{id?}");
});
}
private async Task CreateRoles(IServiceProvider serviceProvider)
{
//initializing custom roles
var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
string[] roleNames = { "Admin", "Manager", "Member" };
IdentityResult roleResult;
foreach (var roleName in roleNames)
{
roleResult = await RoleManager.CreateAsync(new IdentityRole(roleName));
}
}
}
}
The Identity UI is implemented using Razor Pages. For endpoint-routing to map these, add a call to MapRazorPages in your UseEndpoints callback:
app.UseEndpoints(endpoints =>
{
// ...
endpoints.MapRazorPages();
});

Assigning a user to a Role inside asp.net core will return this error "You do not have access to this resource."

I created a new asp.net core web application which uses individual user accounts. now i am trying to implement a simple role assignment scenario.
so i register a test user, where the user got added inside the AspNetUser table:-
then i add a new Role named "Administrator" inside the AspNetRole:-
then i added a new AspNetUserRole to link the user to the Role:-
then i added the following Authorize annotation on the About action method:-
[Authorize(Roles = "Administrator")]
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
but when i try to access the About action method using the user, i got this error:-
You do not have access to this resource."
EDIT
Here is the startup.cs , which i have not modified, so i think it contain the built-in code:-
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using WebApplication2.Data;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace WebApplication2
{
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.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
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)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
I guess you manually create role and link role in AspNetUserRoletable after creating your user . Please don't forget to Logout user and login again , so role claims will get/update the new added role .
Your identity service is not configured for roles. AddDefaultIdentity cannot handle roles. You need AddIdentity
Instead of:
services.AddDefaultIdentity<IdentityUser>().AddEntityFrameworkStores<ApplicationDbContext>();
Try:
services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
Short answer
Add IdentityRole :
services.AddDefaultIdentity<IdentityUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
Long Answer
For properly using of roles/policies, you need to follow the below steps:
configure ApplicationDbContext for using IdentityRole
configure Identity service to use IdentityRole
configure application cookie
define authorization policies
configure authorization for razor pages
Notice : if you are using razor pages, Authorization attributes must be applied to the PageModel model not the actions
before proceeding with the solution, it is worth to mention that it is a best practice to use custom user and role models instead of IdentityUser and IdentityModel. This will help you add custom fields to the user and role easily.
So, first lets create our custom user and role models:
public class AppUser : IdentityUser
{
//custom fields can be defined here
}
public class AppRole : IdentityRole
{
//custom fields can be defined here
}
public class AppUserRole : IdentityUserRole<string>
{
public virtual AppUser User { get; set; }
public virtual AppRole Role { get; set; }
}
Now we can start with configuring ApplicationDbContext:
public class ApplicationDbContext : IdentityDbContext<AppUser, AppRole, string, IdentityUserClaim<string>, AppUserRole, IdentityUserLogin<string>, IdentityRoleClaim<string>, IdentityUserToken<string>>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
// AppUserRole relationship solution from so
// https://stackoverflow.com/questions/51004516/net-core-2-1-identity-get-all-users-with-their-associated-roles/51005445#51005445
builder.Entity<AppUserRole>(userRole =>
{
userRole.HasKey(ur => new { ur.UserId, ur.RoleId });
userRole.HasOne(ur => ur.Role)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.RoleId)
.IsRequired();
userRole.HasOne(ur => ur.User)
.WithMany(r => r.UserRoles)
.HasForeignKey(ur => ur.UserId)
.IsRequired();
});
}
}
}
configuring Identity
services.AddIdentity<AppUser, AppRole>(ops =>
{
ops.SignIn.RequireConfirmedEmail = true;
// Lockout settings
ops.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
ops.Lockout.MaxFailedAccessAttempts = 9;
ops.Lockout.AllowedForNewUsers = true;
// User settings
ops.User.RequireUniqueEmail = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
configure application cookie
services.ConfigureApplicationCookie(ops =>
{
// Cookie settings
ops.Cookie.HttpOnly = false;
ops.ExpireTimeSpan = TimeSpan.FromMinutes(30);
// If the LoginPath isn't set, ASP.NET Core defaults the path to /Account/Login.
ops.LoginPath = $"/Identity/Account/Login";
// If the AccessDeniedPath isn't set, ASP.NET Core defaults the path to /Account/AccessDenied.
ops.AccessDeniedPath = $"/Identity/Account/AccessDenied";
ops.SlidingExpiration = true;
});
define authorization policies
services.AddAuthorization(ops =>
{
ops.AddPolicy("Administrator", policy =>
{
policy.RequireRole("Administrator");
});
});
Now it is possible to use roles/policies in different ways:
1- define authorization policies in startup
services.AddMvc()
.AddRazorPagesOptions(ops =>
{
ops.Conventions.AuthorizeFolder("/", "Administrator");
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
2- apply authorization attributes on actions in case of MVC
[Authorize(Roles = "Administrator")]
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
3- or apply policy on PageModel for Razor Pages
[Authorize(Policy = "Administrator")]
public class AboutModel : PageModel
{
//-----
}
[UPDATE]
following to your comment below;
Let's consider that you will develop a news website management panel; basically you will need roles like Admins to manage the site settings and Authors to post the news pages, and probably Managers to approve the posted news. With this scenario you can survive with the default Identity settings and role based authorization.
But for example; if you need to allow only authors with more than 100 posted articles and are older than 25 to be able to approve their posts without the Managers approval then you need to customize the IdentityUser and use policy/claim based authorization, in this case the long answer will help you more to develop the application.
you can read more about authorization in the docs

.NET CORE web api Changes not detected

I'm currently working on a VueJS app using .NET Core 2.2 for the back-end part.
I was working on it for a few months but it suddenly stopped working like a charm when I updated from 2.0 to 2.2.
My web API changes are not detected and I don't know why.
For instance, I have a few controllers and whenever I change them, and then use the web API, the changes are not made. I can even delete the whole file and the web API using this file will still be working!
Another problem I get is that when I create new controller files, it's not detected; I'm stuck with my old controllers, which I'm not able to update.
Others files updates are detected (at least if I change the VueJS front-end)
I can also change the providers, delete whatever file used for the web API, changes are not detected. It may be a configuration issue?
Is there anything I could try to make things update again?
Update: I can change whatever I want in the back-end and it will do nothing. Compilations errors are the only problem I have to care about, it's like the app doesn't use the code anymore.
Here is an example I can provide:
I have a controller InterventionController which retrieve data about operations (I am french in a french context so variables names, etc will be in french) :
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Vue2Spa.Models;
using Vue2Spa.Providers;
namespace Vue2Spa.Controllers
{
[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class InterventionController : Controller
{
private readonly IInterventionProvider interventionProvider;
public InterventionController(IInterventionProvider interventionProvider)
{
this.interventionProvider = interventionProvider;
}
[HttpGet("[action]")]
public IActionResult Interventions([FromQuery(Name = "from")] int from = 0, [FromQuery(Name = "to")] int to = 5000)
{
var quantity = to - from;
if (quantity <= 0)
{
return BadRequest("La quantité doit être positive !");
}
else if (from < 0)
{
return BadRequest("Vous devez spécifier un indice de départ non nul !");
}
var allInterventions = interventionProvider.GetInterventions();
var result = new
{
TotalInterventions = allInterventions.Count,
Interventions = allInterventions.Skip(from).Take(quantity).ToArray()
};
return Ok(result);
}
}
// Others methods not useful for my example
}
It calls a provider which has the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Vue2Spa.Models;
namespace Vue2Spa.Providers
{
public class DBInterventionProvider : IInterventionProvider
{
private List<Intervention> interventions { get; set; }
DbContextOptionsBuilder<DepouillementTestContext> optionsBuilder = new DbContextOptionsBuilder<DepouillementTestContext>();
public DBInterventionProvider()
{
optionsBuilder.UseSqlServer(credentials); // Credentials are correct but not including it there for obvious reasons
using (var context = new LECESDepouillementTestContext(optionsBuilder.Options))
{
interventions = context.Intervention.ToList();
}
}
public List<Intervention> GetInterventions()
{
using (var context = new LECESDepouillementTestContext(optionsBuilder.Options))
{
interventions = context.Intervention.ToList();
}
return interventions;
}
// Others methods not useful for this example
}
}
I can delete these files, and I'm still able to access my operations web API
If needed, here is my startup.cs file:
using System;
using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.SpaServices.Webpack;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Vue2Spa.Models;
namespace Vue2Spa
{
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)
{
// Add framework services.
services.AddMvc();
// Additional code for SQL connection
services.AddDbContext<DepouillementTestContext>(options =>
{
options.UseSqlServer(Configuration["ConnectionString"],
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.
MigrationsAssembly(
typeof(Startup).
GetTypeInfo().
Assembly.
GetName().Name);
//Configuring Connection Resiliency:
sqlOptions.
EnableRetryOnFailure(maxRetryCount: 5,
maxRetryDelay: TimeSpan.FromSeconds(30),
errorNumbersToAdd: null);
});
// Changing default behavior when client evaluation occurs to throw.
// Default in EFCore would be to log warning when client evaluation is done.
options.ConfigureWarnings(warnings => warnings.Throw(
RelationalEventId.QueryClientEvaluationWarning));
});
// Provider pour les interventions
services.AddSingleton<Providers.IInterventionProvider, Providers.DBInterventionProvider>();
}
// 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.UseDeveloperExceptionPage();
// Webpack initialization with hot-reload.
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true,
});
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
}
}
}
Thanks in advance,
Well I've found why I had this problem, and I feel kinda dumb for that but well, it's working now.
I didn't change my launch.json when I upgraded from .NETCORE 2.0 to 2.2, all I had to do was changing
"program": "${workspaceFolder}/content/bin/Debug/netcoreapp2.0/Vue2Spa.dll",
by
"program": "${workspaceFolder}/content/bin/Debug/netcoreapp2.2/Vue2Spa.dll",
For more informations, see : https://learn.microsoft.com/en-us/aspnet/core/migration/21-to-22?view=aspnetcore-2.2&tabs=visual-studio

EF7 Beta 4 : AddEntityFramework dont accept argument (Configuration)

I am going through this example:
http://stephenwalther.com/archive/2015/01/17/asp-net-5-and-angularjs-part-4-using-entity-framework-7
and i am struggling with this code part:
using Microsoft.AspNet.Builder;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Data.Entity;
using creaservo.com.Models;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.AspNet.Hosting;
namespace creaservo.com
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
// Setup configuration sources.
Configuration = new Configuration()
.AddJsonFile("config.json")
.AddEnvironmentVariables();
}
public IConfiguration Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
// Register Entity Framework
services.AddEntityFramework(Configuration)
.AddSqlServer()
.AddDbContext<MoviesAppContext>();
}
public void Configure(IApplicationBuilder app)
{
app.UseMvc();
}
}
}
The Problem is with
// Register Entity Framework
services.AddEntityFramework(Configuration)
.AddSqlServer()
.AddDbContext<MoviesAppContext>();
where i get a build error:
Error CS1501 No overload for method 'AddEntityFramework' takes 1 arguments
I saw in a lot of other examples the same use of a argument for Configuration.
No idea, what's wrong....
It looks like the tutorial you're following is using an older version of the EF7 framework. EntityFramework 7 beta 4 no longer accepts any parameters to AddEntityFramework. It looks like beta 5 is still on this same track, too.
I believe what you're looking for is this:
// Register Entity Framework
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<MoviesAppContext>(options =>
{
options.UseSqlServer(Configuration.Get("Data:DefaultConnection:ConnectionString"));
});
This simplifies the structure that you need in the configuration file, because the MoviesAppContext only needs the connection string, not the EntityFramework and Data elements.