Як прочитати рядок підключення в .NET Core?


108

Я хочу прочитати лише рядок з'єднання з файлу конфігурації, і для цього додати в проект мій файл з назвою "appsettings.json" і додати до нього цей вміст:

{
"ConnectionStrings": {
  "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-

 WebApplica71d622;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
    "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
    "Default": "Debug",
    "System": "Information",
    "Microsoft": "Information"
   }
 }
}

На ASP.NET я використав це:

 var temp=ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;

Тепер, як я можу прочитати "DefaultConnection" у C # та зберегти його на рядковій змінній у .NET Core?


Відповіді:


101

Це можна зробити за допомогою методу розширення GetConnectionString:

string conString = Microsoft
   .Extensions
   .Configuration
   .ConfigurationExtensions
   .GetConnectionString(this.Configuration, "DefaultConnection");

System.Console.WriteLine(conString);

або зі структурованим класом для DI:

public class SmtpConfig
{
    public string Server { get; set; }
    public string User { get; set; }
    public string Pass { get; set; }
    public int Port { get; set; }
}

Стартап:

public IConfigurationRoot Configuration { get; }


// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // http://developer.telerik.com/featured/new-configuration-model-asp-net-core/
    // services.Configure<SmtpConfig>(Configuration.GetSection("Smtp"));
    Microsoft.Extensions.DependencyInjection.OptionsConfigurationServiceCollectionExtensions.Configure<SmtpConfig>(services, Configuration.GetSection("Smtp"));

А потім у домашньому контролері:

public class HomeController : Controller
{

    public SmtpConfig SmtpConfig { get; }
    public HomeController(Microsoft.Extensions.Options.IOptions<SmtpConfig> smtpConfig)
    {
        SmtpConfig = smtpConfig.Value;
    } //Action Controller


    public IActionResult Index()
    {
        System.Console.WriteLine(SmtpConfig);
        return View();
    }

з цим у appsettings.json:

"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-WebApplica71d622;Trusted_Connection=True;MultipleActiveResultSets=true"
},

"Smtp": {
    "Server": "0.0.0.1",
    "User": "user@company.com",
    "Pass": "123456789",
    "Port": "25"
  }

9
Configureє методом розширення. Його слід використовувати найчастіше так: services.Configure<SmtpConfig>(Configuration.GetSection("Smtp"));Звичайно, це майже те саме, але я думаю, що люди, які не знають, просто почнуть робити це "неправильним" способом, використовуючи некоментовану лінію, тому, можливо, найкраще видалити лінію. ;)
Джеймс Вілкінс

@James Wilkins: Дуже вагомі проблеми. Однак я фактично віддаю перевагу цьому позначенням, ніж використовувати його як метод розширення - таким чином я знаю, що робиться куди, і можу копіювати та вставляти з 1 місця в інше, не виникаючи проблем через відсутність просторів імен імпорту. Єдина проблема полягає в тому, що MS використовує простори імен для систематики замість запобігання зіткненням імен - через це простори імен занадто довгі. Крім того, якщо ви видалите namspaces та скористаєтесь методами розширення, той самий тип людей почне скаржитися на те, що код не складається. Не всі використовують IDE, тому краще таким чином.
Стефан Штайгер

3
@JedatKinports: Ні, лише ін'єкція. Навіть якщо ви будете писати статичний метод, вам все одно знадобиться конфігурація. Ви можете просто прочитати файл JSON / YAML вручну. Але це усуне перезаписи, такі як usersecrets або інші (наприклад, конфігурація з реєстру).
Стефан Штайгер

1
Я отримую помилку: "MyClass містить визначення" Конфігурація "..."
Роберт Сміт

3
На що посилається "this.Configuration" у частині рядка з'єднання? GetConnectionString (this.Configuration, "DefaultConnection")
MC9000

111

Опублікована відповідь чудова, але не відповіла безпосередньо на той самий питання, який я мав про читання в рядку з'єднання. Завдяки багатому пошуку я знайшов дещо простіший спосіб зробити це.

У Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    ...
    // Add the whole configuration object here.
    services.AddSingleton<IConfiguration>(Configuration);
}

У свій контролер додайте поле для конфігурації та параметр для нього на конструкторі

private readonly IConfiguration configuration;

public HomeController(IConfiguration config) 
{
    configuration = config;
}

Тепер пізніше у коді перегляду ви можете отримати доступ до нього так:

connectionString = configuration.GetConnectionString("DefaultConnection");

2
Не хотів би так зробити. Якщо ви працюєте без сутності, вам краще зареєструвати фабрику з'єднань як одиночну, наприклад, використовувати з даппером. Після цього ви можете все-таки викрити властивість connectionString, якщо вам потрібно, але я думаю, що це не буде потрібно в 99% випадків.
Стефан Штайгер

2
Але як отримати доступ до конфігурації в моделях замість контролера?
Танмай

2
Чим більше я читаю і пробую речі, тим більше я усвідомлюю, що отримання з'єднання - це головне завдання. Я просто отримую нулі незалежно від того, що намагаюся.
MC9000

7
Так. Занадто багато комп'ютерних фахівців, які створюють величезні високі плоди, щоб сказати "Hello World". Неймовірно. Ентропія в кращому випадку.
JustJohn

2
@JustJohn: Я розумію вашу скаргу, але правильна конструкція перевірена, і це означає, що ви повинні пройти залежності в конструкторі, інакше ваша програма / фреймворк не може бути перевірена одиницею. Це також належна конструкція, оскільки ви можете просто замінити один компонент іншим, не змінюючи цілу партію коду. Якщо ви не хочете передавати 100 аргументів навколо, ви також можете передати System.IServiceProvider в клас, тоді ви можете отримати там залежності. Але інша сторона монети полягає в тому, що це має додаткову складність.
Стефан Штайгер

18

Додаткову інформацію див. За посиланням: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-strings

JSON

    {
      "ConnectionStrings": {
        "BloggingDatabase": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;"
      },
    }

C # Startup.cs

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

EDIT: aspnetcore, починаючи з 3.1: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1


Чому слід мати файл JSON ConnectionStringsзамість ConnectionString? Тому що коли я використовував ConnectionString, то ми ставали нульовими.
Віджай

@Vijay Спробуйте скористатися встановленим методом;) Перегляньте додане посилання.
markokstate

1
Цей метод здається застарілим станом на Microsoft.Extensions.Configuration(3.1.5)
Ju66ernaut

7

Я вирішив це, щоб вирішити це, це використовувати AddJsonFile в програмі Builder при запуску (що дозволяє йому знаходити конфігурацію, що зберігається у файлі appsettings.json), а потім використовувати її для встановлення приватної змінної _config

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();
        _config = builder.Build();
    }

І тоді я міг би встановити конфігураційний рядок наступним чином:

var connectionString = _config.GetConnectionString("DbContextSettings:ConnectionString"); 

Це на ядрі dotnet 1.1


5
як я можу отримати доступ до _config у своєму контролі?
сонячно

Додавши його до контейнера DI в ConfigureServices в Startup.cs.
Стефан Штайгер

3

ASP.NET Core ( в моєму випадку 3.1 ) надає нам ін'єкції Constructor в контролери , тому ви можете просто додати наступний конструктор:

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    private readonly IConfiguration m_config;

    public TestController(IConfiguration config)
    {
        m_config = config;
    }

    [HttpGet]
    public string Get()
    {
        //you can get connection string as follows
        string connectionString = m_config.GetConnectionString("Default")
    }
}

Ось як може виглядати appsettings.json:

{
    "ConnectionStrings": {
        "Default": "YOUR_CONNECTION_STRING"
        }
}

0

Є й інший підхід. У моєму прикладі ви бачите деяку бізнес-логіку в класі репозиторіїв, які я використовую при введенні залежності в ASP .NET MVC Core 3.1.

І тут я хочу скористатися connectiongStringцією логікою бізнесу, оскільки, ймовірно, інший репозиторій взагалі матиме доступ до іншої бази даних.

Ця схема дозволяє вам в одному сховищі бізнес-логіки мати доступ до різних баз даних.

C #

public interface IStatsRepository
{
            IEnumerable<FederalDistrict> FederalDistricts();
}

class StatsRepository : IStatsRepository
{
   private readonly DbContextOptionsBuilder<EFCoreTestContext>
                optionsBuilder = new DbContextOptionsBuilder<EFCoreTestContext>();
   private readonly IConfigurationRoot configurationRoot;

   public StatsRepository()
   {
       IConfigurationBuilder configurationBuilder = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory)
           .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
       configurationRoot = configurationBuilder.Build();
   }

   public IEnumerable<FederalDistrict> FederalDistricts()
   {
        var conn = configurationRoot.GetConnectionString("EFCoreTestContext");
        optionsBuilder.UseSqlServer(conn);

        using (var ctx = new EFCoreTestContext(optionsBuilder.Options))
        { 
            return ctx.FederalDistricts.Include(x => x.FederalSubjects).ToList();
        }
    }
}

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "EFCoreTestContext": "Data Source=DESKTOP-GNJKL2V\\MSSQLSERVER2014;Database=Test;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

-1

У мене є бібліотека доступу до даних, яка працює як з ядром .net, так і з мережею .net.

фокус полягав у основних проектах .net, щоб зберегти рядки підключення у файлі XML під назвою "app.config" (також для веб-проектів) та позначити його як "копіювати у вихідний каталог",

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="conn1" connectionString="...." providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

ConfigurationManager.ConnectionStrings - прочитає рядок з'єднання.

    var conn1 = ConfigurationManager.ConnectionStrings["conn1"].ConnectionString;

Якщо ви використовуєте .NET Core, найкраще прийняти його конфігураційну схему, а не вбудовану в шаблон .NET Framework.
Симетричний

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.