Reputation: 4249
I am brand new to both .Net Core and to Entity Framework. I am trying to learn both technologies, by following some tutorial, but I am struggling. My Web API project has two controllers - the wizard generated ValuesController.cs that gets created when creating a new Core Web API project, and a second controller I added called FilesController.cs.
My appsettings.json:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"ConnectionStrings": {
" \"PropWorxConnection\"": "server=a.b.com;user id=propworx;persistsecurityinfo=True;database=abcde;password=12345"
}
}
My Startup.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MySQL.Data.EntityFrameworkCore.Extensions;
namespace PropWorxAPI
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<Models.PropWorxDbContext>(options =>
options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseMvc();
}
}
}
A simple model:
namespace PropWorxAPI.Models
{
[Table("files")]
public partial class File
{
public int ID { get; set; }
public string FileNum { get; set; }
}
}
My Context:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MySQL.Data.EntityFrameworkCore.Extensions;
namespace PropWorxAPI.Models
{
public class PropWorxDbContext : DbContext
{
private readonly string _connectionString;
public PropWorxDbContext(string connectionString)
{
_connectionString = connectionString;
}
public PropWorxDbContext(DbContextOptions<PropWorxDbContext> options) : base(options)
{
}
public DbSet<Models.File> Files { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.File>().ToTable("Files");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySQL(_connectionString);
base.OnConfiguring(optionsBuilder);
}
}
}
and my controller:
using Microsoft.AspNetCore.Mvc;
using PropWorxAPI.Models;
namespace PropWorxAPI.Controllers
{
[Route("api/[controller]")]
public class FilesController : Controller
{
private readonly PropWorxDbContext _context;
public FilesController(PropWorxDbContext context)
{
_context = context;
}
[HttpGet]
public string Get()
{
return "Controller Working!!!";
}
}
}
Now, when I run it (F5), it opens up Edge and goes to http://localhost:51932/api/values. This displays this output:
["value1","value2"]
So it's defaulting to ValuesController (How do I changed that???). Anyway, the important thing is the auto generated ValuesController works. I now manually change the URL to point to the FilesController I created, i.e.
http://localhost:51932/api/files
...and I get this:
HTTP 500 error That’s odd... the website can’t display this page
Now, if I remove the context argument from my FilesController - i.e. I go from:
public FilesController(PropWorxDbContext context)
{
_context = context;
}
to
public FilesController()
{
}
then it works and it correctly displays:
this is the files controller
Any ideas why? Thanks, and sorry for the overly verbose post...
Upvotes: 1
Views: 1335
Reputation: 4249
Figured it out - my ConnectionStrings in appsettings.json wasn't formatted correctly (I had some weird forward slashes - not sure why... thanks for your help though Ahmar and user1900799 - truly appreciated!
Upvotes: 0
Reputation: 1809
Your dependency injection isn't working. When the framework tries to create a new FilesController it can't because it doesn't know what PropWorxContext is.
namespace PropWorxAPI.Models
{
public class PropWorxDbContext : DbContext
{
private readonly string _connectionString;
//public PropWorxDbContext(string connectionString)
//{
// _connectionString = connectionString;
//}
public PropWorxDbContext(DbContextOptions<PropWorxDbContext> options) : base(options)
{
}
public DbSet<Models.File> Files { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.File>().ToTable("Files");
}
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
//{
// optionsBuilder.UseMySQL(_connectionString);
// base.OnConfiguring(optionsBuilder);
//}
}
}
You dont need the connection string or the OnConfiguring override because you are doing these things in your Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// This must come before MVC
services.AddDbContext<Models.PropWorxDbContext>(options => options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));
services.AddMvc();
}
The services.AddDbContext line registers your database with dependency injection. Which enables your controller to work using the correct constructor
public FilesController(PropWorxDbContext context)
{
_context = context;
}
I think the only problem you have is the unnecessary code in your DbContext which would prevent the dependency injection container from newing it up.
Upvotes: 2
Reputation: 3877
Remove these two lines from OnConfiguring
method.
optionsBuilder.UseMySQL(_connectionString);
base.OnConfiguring(optionsBuilder);
You already tell the provider in ConfigureServices
method of startup.cs
services.AddDbContext<Models.PropWorxDbContext>(options =>
options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));
Updated DbContext
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using MySQL.Data.EntityFrameworkCore.Extensions;
namespace PropWorxAPI.Models
{
public class PropWorxDbContext : DbContext
{
public PropWorxDbContext(DbContextOptions<PropWorxDbContext> options) : base(options)
{
}
public DbSet<Models.File> Files { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.File>().ToTable("Files");
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
}
}
}
Upvotes: 2