【问题标题】:Access Connection String inside an ASP.NET Core controller访问 ASP.NET Core 控制器内的连接字符串
【发布时间】:2018-05-11 15:51:02
【问题描述】:

我正在使用 C# 和 .NET Framework 4.7 开发 ASP.NET Core 2.0.2 Web API。

我想在方法的控制器中从appsettings.json 获取连接字符串。

我是在 Startup.cs 中完成的:

using Microsoft.Extensions.Configuration;

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.AddDbContext<MyContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("MyContext")));

        [ ... ]
}

但我不知道如何在控制器中执行此操作。我找到了这个教程,Configure an ASP.NET Core App,但它使用一个类来访问配置的选项,public class MyOptions

我尝试过像Startup.csConfiguration.GetConnectionString("MyContext") 那样做,但它无法识别Configuration 类。

我的问题是: 如何在控制器中获取连接字符串?

【问题讨论】:

标签: c# asp.net-core configuration


【解决方案1】:

你可以直接将IConfiguration configuration注入你的控制器(默认注册在DI容器中):

// using Microsoft.Extensions.Configuration;

public class YourController : Controller
{
      public YourController (IConfiguration configuration)
      {
           var connString = Configuration.GetConnectionString("MyContext");
      }

}

但无论如何考虑使用IOptions 模式,因为它会更灵活。

public class MyOptions
{
    public string ConnString { get; set; }
}

public void ConfigureServices(IServiceCollection services)
{ 
    // Adds services required for using options.
    services.AddOptions();

    services.Configure<MyOptions>(myOptions =>
    {
        myOptions.ConnString = Configuration.GetConnectionString("MyContext");
    });

    ...
}

然后

  public YourController ((IOptions<MyOptions> optionsAccessor)
  {
      var connString = optionsAccessor.Value.ConnString;
  }

【讨论】:

    【解决方案2】:

    您可以将IConfiguration 本身注入您的控制器并获取连接字符串:

    public class HomeController : Controller {
        private readonly string _connectionString;
        public HomeController(IConfiguration config) {
            _connectionString = config.GetConnectionString("MyContext");
        }
    }
    

    【讨论】:

      【解决方案3】:

      你不需要你的连接字符串,你已经准备好注入你的 dbcontext。所以你基本上可以只注入你的 dbcontext。 (不要在您的控制器中执行此操作,并将其分开,并创建一个存储库或其他东西并注入它)。

      您需要在启动时添加 1 次额外注入:

      services.AddScoped<IDataContext, DataContext>();
      

      你的上下文应该是这样的:

      public class DataContext : DbContext, IDataContext
      {
          public DbSet<User> Users { get; set; }
      
          public DataContext(DbContextOptions options) : base(options)
          {
          }
      }
      

      所以你可以在任何地方注入你的上下文。

      也许这不是您要寻找的答案。在这种情况下,您可以添加一个模型并将其绑定到您的配置中并注入您的模型

      类似:

      services.Configure<AssetProviderServiceClientConfig>(
                  Configuration.GetSection("AssetProviderServiceClient"));
      

      然后您可以注入您的选项,例如

      private readonly SchedulerConfig _config;
      
      public YourController(IOptions<SchedulerConfig> config)
      {
          _config = config.Value;
      }
      

      干杯!

      编辑: 执行SP;

      如果您的上下文被注入,您可以执行以下操作:

       var command = databaseContext.database.GetDbConnection().CreateCommand();
       cmd.CommandText = "your SP";
       cmd.CommandType = CommandType.StoredProcedure;
       using (var reader = cmd.ExecuteReader())
       {
        var entitites = reader.MapToList<Entity>();
       }
      

      也许有些行不正确...内存不足:)

      【讨论】:

      • 我需要在 ADO.NET 中使用的连接字符串来执行存储过程。
      【解决方案4】:

      你可以使用 DbContextDatabase.GetDbConnection().ConnectionString 获取指定的上下文连接字符串,像这样

      public HomeController(DbContext context)
          {
              var connectionString = context.Database.GetDbConnection().ConnectionString;
          }
      

      更新: 或者你可以像这样创建委托

      public delegate string ConnectionStringExporter();
      

      然后注册为

      services.AddSingleton<ConnectionStringExporter>(() => Configuration.GetConnectionString("Default"));
      

      在控制器中,您可以将其注入为

      public HomeController( ConnectionStringExporter exporter)
      

      那么你可以通过var connectionString = exporter();获取连接字符串

      您还可以添加具有指定连接字符串名称的委托参数。喜欢public delegate string ConnectionStringExporter(string name);

      【讨论】:

      • 如果我以这种方式获取连接字符串,它不包含数据库密码。
      猜你喜欢
      • 1970-01-01
      • 2018-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-18
      • 2022-10-25
      • 1970-01-01
      • 2018-09-07
      相关资源
      最近更新 更多