【问题标题】:.Net Core 3 / Entity Framework Core putting connection string in Appsettings.json not working.Net Core 3 / Entity Framework Core 将连接字符串放在 Appsettings.json 中不起作用
【发布时间】:2023-03-18 03:35:01
【问题描述】:

对 .NET Core 还是个新手,但我正在尝试将我的连接字符串放在 Appsettings.json 文件中。我正在关注Microsoft document 上的操作方法,我认为我的所有设置都是正确的。

项目将编译并运行,但是当我点击 API 时出现错误

没有为此 DbContext 配置数据库提供程序。

我使用了 EF Core 在我的上下文中放置的连接字符串,只是将其注释掉,因此DbContextOnConfiguring 中实际上没有任何内容。这是连接到 Oracle 数据库。

ModelContext.cs

public partial class ModelContext : DbContext
{
    public ModelContext()
    {
    }

    public ModelContext(DbContextOptions<ModelContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Customer> Customer{ get; set; }
    public virtual DbSet<HubToken> HubToken{ get; set; }
    public virtual DbSet<Token> Token { get; set; } 

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        //if (!optionsBuilder.IsConfigured)
        //{

        //    //optionsBuilder.UseOracle("user id=myusername;password=mypassword;data source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=myserver)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=*****)))");
        //}
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Token>().HasNoKey();

        modelBuilder.HasAnnotation("Relational:DefaultSchema", "MySCHEMA");
     }

Appsettings.json

 "ConnectionStrings": {
    "DbConnection": "user id=myusername;password=mypassword;data source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=servername)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=***)))"
  }

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
     services.AddControllersWithViews();

     services.AddDbContext<ModelContext>(options => {
                options.UseOracle(Configuration.GetConnectionString("DbConnection"));
     });
}

更新

调用 ModelContext 的代码。我最初使用注释掉的“使用”语句来创建上下文。这就是我在 .Net Framework 中的做法,但 Core 似乎有所不同。然后根据一些建议,我尝试使用 using 语句尝试将连接字符串传递给 ModelContext,但它也不喜欢那样,因为此时连接字符串不可用。在将连接字符串传递给 ModelContext 之前,我已经尝试过先获取连接字符串,但是这也不起作用,我只是不记得它是什么,因为我已经尝试了几件事。我会说,至少目前看来,.Net 的 EF 似乎要简单得多。 DbContext 会帮我从 app.config 或 web.config 获取连接字符串。现在似乎在 Core 中做这件事需要付出更多努力,但这可能只是因为我对 Core 的工作方式还很陌生。

//using (var ctx = new ModelContext())
            using (var ctx = new ModelContext(configuration.GetConnectionString("DbConnection")))
            {
                //Run the query and see if there are any results returned.
                var results = ctx.Token.FromSqlRaw(sbQuery.ToString()).ToList();

                if (results == null || results.Count == 0)
                {
                    _logger.LogInformation("Api-Token not found in database. Access denied. Customer: {0} | Token: {1}", customer.ToString(), token.ToString());

                    context.Result = new BadRequestObjectResult("Access Denied. Invalid Token");
                    return;
                }

                if (!context.ModelState.IsValid)
                {
                    _logger.LogInformation("Model is in-valid.");
                    context.Result = new BadRequestObjectResult(context.ModelState);
                }

                _logger.LogInformation("Api-Token is valid.");
                return;
            }

【问题讨论】:

  • 你能把你的整个ModelContext 班级发上来吗?
  • 我在帖子中添加了ModelContext代码。
  • public ModelContext()方法注释掉怎么样?只保留ModelContext(DbContextOptions&lt;ModelContext&gt; options)
  • @Bemn 我尝试将其注释掉,但它需要它。没有它就无法构建。
  • 到目前为止,您的代码没有任何问题。请显示使用ModelContext 类的代码/类,包括它如何获取类的实例,例如通过使用构造函数依赖注入,或GetService()new ModelContext()。看起来您使用的 ModelContext 类实例与您之前通过 services.AddDbContext&lt;ModelContext&gt;() 调用设置的实例不同。

标签: c# asp.net-core .net-core entity-framework-core connection-string


【解决方案1】:

经过更多的研究和玩耍,我终于让它工作了。我正在发布我的更新,希望它能帮助其他人。

将我的连接字符串添加到appsettings.json 文件

"ConnectionStrings": {
    "DbConnection": "user id=myusername;password=mypassword;data source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=servername)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=***)))"
  }

然后将上下文信息添加到 Startup.cs 文件中的 ConfigurationServices 中。我相信这会将信息添加到依赖注入容器中。我正在使用 Oracle,但如果需要,您只需更改为 options.UseSqlServer(connstring);。您可以通过在调试模式下放置断点来验证正确的连接字符串信息。

public void ConfigureServices(IServiceCollection services)
        {
            //setting connstring separately here just to be able confirm correct value. 
            var connstring = Configuration.GetConnectionString("DbConnection");
            services.AddDbContext<ModelContext>(options =>
            {
                options.UseOracle(connstring);
            });
        }

在您的 Controller/Class 中,将上下文添加到页面属性并使用类构造函数从 DI 容器中获取 DbContext。然后使用using 语句并引用具有连接字符串信息的本地属性。

    public class TokenAuthorizationFilter : IAuthorizationFilter
        {
        private readonly ModelContext _context;
                private readonly ILogger<TokenAuthorizationFilter> _logger;
                public TokenAuthorizationFilter(ILogger<TokenAuthorizationFilter> logger, ModelContext context)
                {
                    _logger = logger;
                    _context = context;
                }
                
                public void OnAuthorization(AuthorizationFilterContext context)
                {
                    _logger.LogInformation("Authorizing Api-Token.");
        
                    //Get the values from the Request Header
                    context.HttpContext.Request.Headers.TryGetValue("Api-Token", out var token);
                    context.HttpContext.Request.Headers.TryGetValue("Customer", out var customer);
        
                    var sbQuery = new System.Text.StringBuilder();
                    sbQuery.Append("select * from YourUserTable ");
                    sbQuery.Append("where username=customer and password=token");
        
                    using (_context)
                    {
                        //Run the query and see if there are any results returned.
                        var results = _context.Token.FromSqlRaw(sbQuery.ToString()).ToList();
        
                        if (results == null || results.Count == 0)
                        {
                            _logger.LogInformation("Api-Token not found in database. Access denied. Customer: {0} | Token: {1}", customer.ToString(), token.ToString());
        
                            context.Result = new BadRequestObjectResult("Access Denied. Invalid Token");
                            return;
                        }
        
                        if (!context.ModelState.IsValid)
                        {
                            _logger.LogInformation("Model is in-valid.");
                            context.Result = new BadRequestObjectResult(context.ModelState);
                        }
        
                        _logger.LogInformation("Api-Token is valid.");
                        return;
                    }
                }
}

【讨论】:

    【解决方案2】:

    您可以使用Configuration 类中的GetSection 方法来获取您的连接字符串

    Startup.cs

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
    
            services.AddDbContext<ModelContext>(options => {
                options.UseOracle(Configuration.GetSection("ConnectionStrings")["DbConnection"]);
            });
        }
    

    【讨论】:

    • 我喜欢这种获取 ConnectionString 的方式,并且可能会保留它,但它并没有解决问题。
    猜你喜欢
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    相关资源
    最近更新 更多