带有EF的.Net Core Web API

时间:2017-01-12 10:00:50

标签: asp.net-core asp.net-core-mvc asp.net-core-webapi

我对.Net Core和Entity Framework都是全新的。我正在尝试通过一些教程来学习这两种技术,但我正在努力。我的Web API项目有两个控制器 - 向导生成在创建新的Core Web API项目时创建的ValuesController.cs,以及我添加的第二个控制器,名为FilesController.cs。

我的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"
  }
}

我的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();
        }
    }
}

一个简单的模型:

namespace PropWorxAPI.Models
{
    [Table("files")]
    public partial class File
    {
        public int ID { get; set; }
        public string FileNum { get; set; }
    }
}

我的背景:

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);
        }
    }
}

和我的控制员:

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!!!";
        }
    }
}

现在,当我运行它(F5)时,它会打开Edge并转到 http://localhost:51932/api/values 。这会显示以下输出:

[ “VALUE1”, “值2”]

因此它默认为 ValuesController (我如何更改???)。无论如何,重要的是自动生成的 ValuesController 有效。我现在手动将URL更改为指向我创建的FilesController,即

http://localhost:51932/api/files

......我明白了:

HTTP 500错误 这很奇怪......网站无法显示此页面

现在,如果我从 FilesController 中删除了上下文参数 - 即我来自:

public FilesController(PropWorxDbContext context)
        {
            _context = context;
        }

public FilesController()
        {
        }

然后它可以正常显示:

这是文件控制器

任何想法为什么?谢谢,对于过于冗长的帖子感到抱歉......

3 个答案:

答案 0 :(得分:2)

OnConfiguring方法中删除这两行。

optionsBuilder.UseMySQL(_connectionString);
base.OnConfiguring(optionsBuilder);

您已使用ConfigureServices

startup.cs方法告知提供商
services.AddDbContext<Models.PropWorxDbContext>(options =>
options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));

更新了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)
        {

        }
    }
}

答案 1 :(得分:2)

您的依赖注入不起作用。当框架试图创建一个新的FilesController时,它不能,因为它不知道PropWorxContext是什么。

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);
        //}
    }
}

您不需要连接字符串或OnConfiguring覆盖,因为您正在Startup.cs中执行这些操作

public void ConfigureServices(IServiceCollection services)
{
    // This must come before MVC
    services.AddDbContext<Models.PropWorxDbContext>(options => options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));

    services.AddMvc();

}

services.AddDbContext行使用依赖注入注册您的数据库。这使您的控制器能够使用正确的构造函数

public FilesController(PropWorxDbContext context)
{
    _context = context;
}

我认为你遇到的唯一问题是你的DbContext中不必要的代码会阻止依赖注入容器新建它。

答案 2 :(得分:0)

想出来 - 我在appsettings.json中的ConnectionStrings没有正确格式化(我有一些奇怪的正斜杠 - 不知道为什么......感谢你的帮助,虽然Ahmar和user1900799 - 真的很感激!