从appsettings.json获取ConnectionString而不是在.NET Core 2.0应用程序中硬编码

104

我在 NET Core2.0 应用程序中有以下类。

// required when local database does not exist or was deleted
public class ToDoContextFactory : IDesignTimeDbContextFactory<AppContext>
{
    public AppContext CreateDbContext(string[] args)
    {
        var builder = new DbContextOptionsBuilder<AppContext>();
        builder.UseSqlServer("Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true");
        return new AppContext(builder.Options);
    }
}

如果在运行update-database时,数据库不存在且需要创建,则在Core 2.0中需要此项操作。
升级到ASP.NET Core 2.0后无法创建迁移

我希望不要在这里和appsettings.json两个地方都有ConnectionString,而只在.json文件中存在,所以我尝试替换了

"Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true"
with
ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString
但它不起作用,我得到了空值。
更新1:
只需注意,在Core 2中明确添加.json是不必要的,因此问题不在文件中。
https://andrewlock.net/exploring-program-and-startup-in-asp-net-core-2-preview1-2/

更新2:
此外,我已经在使用Configuration从.json向上下文(Context)发送ConnectionString。
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<AppContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    }
}

但是我无法在ToDoContextFactory中使用这个,因为它没有 Configuration,而且ToDoContextFactory被迁移使用,所以应用程序根本无法运行。

解决方案: 基于 @JRB 的回答,我这样处理:

public AppContext CreateDbContext(string[] args)
{
    string projectPath = AppDomain.CurrentDomain.BaseDirectory.Split(new String[] { @"bin\" }, StringSplitOptions.None)[0];
    IConfigurationRoot configuration = new ConfigurationBuilder()
        .SetBasePath(projectPath)
        .AddJsonFile("appsettings.json")
        .Build();
    string connectionString = configuration.GetConnectionString("DefaultConnection");

    var builder = new DbContextOptionsBuilder<AppContext>();
    builder.UseSqlServer(connectionString);

    return new AppContext(builder.Options);
}

不知道最新版本的情况,但在早期版本中,您仍然需要将.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)添加到您的ConfigurationBuilder中。您是否已经这样做了?'普通'应用程序设置是否正常工作? - Jan_V
1
在Core2.0中,这是自动完成的:https://andrewlock.net/exploring-program-and-startup-in-asp-net-core-2-preview1-2/ - borisdj
在Core2.0中,您可以使用System.AppContext.BaseDirectory来获取基本路径,如果您无法在启动时执行此操作,则可以参考@borisdj的建议:https://github.com/aspnet/Announcements/issues/237。 - William Ardila
3
对于那些想知道SetBasePath来自哪里的人:https://dev59.com/HVYN5IYBdhLWcg3w07Fx#46843572;而`AddJsonFile`来自哪里:https://dev59.com/sF4c5IYBdhLWcg3w7t7E - Adam Houldsworth
谢谢!我认为您应该发布一个单独的答案,而不是将解决方案嵌入问题中。 - Shimmy Weitzhandler
13个回答

0
如果您需要在不同的层中使用:
请创建一个静态类,并将该层上的所有配置属性公开如下:

using Microsoft.Extensions.Configuration;
using System.IO;

namespace Core.DAL
{
    public static class ConfigSettings
    {
        public static string conStr1 { get ; }
        static ConfigSettings()
        {
            var configurationBuilder = new ConfigurationBuilder();
            string path = Path.Combine(Directory.GetCurrentDirectory(), "appsettings.json");
            configurationBuilder.AddJsonFile(path, false);
            conStr1 = configurationBuilder.Build().GetSection("ConnectionStrings:ConStr1").Value;
        }
    }
}


0
  1. 将以下代码添加到 startup.cs 文件中。

    public void ConfigureServices(IServiceCollection services)
    {
        string con = Configuration.GetConnectionString("DBConnection");
        services.AddMvc();
        GlobalProperties.DBConnection = con;//DBConnection 是 GlobalProperties 类的用户定义静态属性
    }
    
  2. Context 类中使用 GlobalProperties.DBConnection 属性。

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {  
              optionsBuilder.UseSqlServer(GlobalProperties.DBConnection);
        }
    }
    

0

这并不是很花哨,但您可以使用回调类,创建一个HostBuilder并将配置设置为静态属性。

对于Asp Core 2.2:

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using System;

namespace Project
{
    sealed class Program
    {
        #region Variables
        /// <summary>
        /// Last loaded configuration
        /// </summary>
        private static IConfiguration _Configuration;
        #endregion

        #region Properties
        /// <summary>
        /// Default application configuration
        /// </summary>
        internal static IConfiguration Configuration
        {
            get
            {
                // None configuration yet?
                if (Program._Configuration == null)
                {
                    // Create the builder using a callback class
                    IWebHostBuilder builder = WebHost.CreateDefaultBuilder().UseStartup<CallBackConfiguration>();

                    // Build everything but do not initialize it
                    builder.Build();
                }

                // Current configuration
                return Program._Configuration;
            }

            // Update configuration
            set => Program._Configuration = value;
        }
        #endregion

        #region Public
        /// <summary>
        /// Start the webapp
        /// </summary>
        public static void Main(string[] args)
        {
            // Create the builder using the default Startup class
            IWebHostBuilder builder = WebHost.CreateDefaultBuilder(args).UseStartup<Startup>();

            // Build everything and run it
            using (IWebHost host = builder.Build())
                host.Run();
        }
        #endregion


        #region CallBackConfiguration
        /// <summary>
        /// Aux class to callback configuration
        /// </summary>
        private class CallBackConfiguration
        {
            /// <summary>
            /// Callback with configuration
            /// </summary>
            public CallBackConfiguration(IConfiguration configuration)
            {
                // Update the last configuration
                Program.Configuration = configuration;
            }

            /// <summary>
            /// Do nothing, just for compatibility
            /// </summary>
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                //
            }
        }
        #endregion
    }
}

从现在开始,您只需在需要它的任何其他类中使用静态Program.Configuration即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接