【问题标题】:.Net Core Web API with EF.Net Core Web API 与 EF
【发布时间】:2017-01-12 10:00:50
【问题描述】:

我对 .Net Core 和 Entity Framework 都是全新的。我正在尝试通过遵循一些教程来学习这两种技术,但我很挣扎。我的 Web API 项目有两个控制器 - 向导生成的 ValuesController.cs 是在创建新的 Core Web API 项目时创建的,我添加的第二个控制器称为 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","value2"]

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

http://localhost:51932/api/files

...我明白了:

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

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

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

public FilesController()
        {
        }

然后它可以正常工作并正确显示:

这是文件控制器

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

【问题讨论】:

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


    【解决方案1】:

    OnConfiguring 方法中删除这两行。

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

    您已经在startup.csConfigureServices 方法中告诉提供者

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

    【讨论】:

    • 非常感谢您的快速回复。好的,我注释掉了这两行,但仍然给我同样的错误:(
    • 如果我从 FilesController 构造函数中删除“DbContext”参数,那么它不再给出错误。但显然这对我没有帮助,因为现在我无法访问我的控制器文件中的上下文......
    • 不需要从控制器中删除只评论我在回答中提到的那些行。
    【解决方案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 中不必要的代码,这会阻止依赖注入容器对其进行更新。

    【讨论】:

    • 非常感谢您的快速回复。好的,我注释掉了两个地方(公共 PropWorxDbContext(string connectionString) 和 OnConfiguring),但仍然给我同样的错误:(
    • 如果我从 FilesController 构造函数中删除“DbContext”参数,那么它就不会再给出错误了。但显然这对我没有帮助,因为现在我无法访问控制器文件中的上下文......
    • @user1900799 您需要移动放置内联服务的位置。AddDbContext(options => options.UseMySQL(Configuration.GetConnectionString("PropWorxConnection")));这必须先于 services.AddMvc();查看我对 Startup.cs 的编辑
    【解决方案3】:

    想通了 - appsettings.json 中的 ConnectionStrings 格式不正确(我有一些奇怪的正斜杠 - 不知道为什么......感谢 Ahmar 和 user1900799 的帮助 - 非常感谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-15
      • 2021-11-20
      • 1970-01-01
      • 2020-07-24
      • 2018-05-08
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      相关资源
      最近更新 更多