Bagaimana cara membaca string koneksi di .NET Core?

108

Saya hanya ingin membaca string koneksi dari file konfigurasi dan untuk ini tambahkan file dengan nama "appsettings.json" ke proyek saya dan tambahkan konten ini ke dalamnya:

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

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

Di ASP.NET saya menggunakan ini:

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

Sekarang bagaimana saya bisa membaca "DefaultConnection" di C # dan menyimpannya pada variabel string di .NET Core?

motevalizadeh
sumber

Jawaban:

101

Anda dapat melakukan ini dengan metode ekstensi GetConnectionString:

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

System.Console.WriteLine(conString);

atau dengan kelas terstruktur untuk DI:

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

Memulai:

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"));

Dan kemudian di pengontrol rumah:

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();
    }

dengan ini di appsettings.json:

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

"Smtp": {
    "Server": "0.0.0.1",
    "User": "[email protected]",
    "Pass": "123456789",
    "Port": "25"
  }
Stefan Steiger
sumber
9
Configureadalah metode ekstensi. Ini harus digunakan paling umum seperti ini: services.Configure<SmtpConfig>(Configuration.GetSection("Smtp"));Tentu, ini hampir sama, tetapi saya pikir orang yang tidak sadar akan mulai melakukannya dengan cara yang "salah", menggunakan garis tanpa komentar, jadi mungkin yang terbaik adalah menghapus garis tersebut. ;)
James Wilkins
@ James Wilkins: Kekhawatiran yang sangat valid. Namun, saya sebenarnya lebih suka notasi ini daripada menggunakannya sebagai metode ekstensi - dengan cara ini saya tahu apa yang sedang dilakukan di mana, dan dapat menyalin-tempel dari satu tempat ke tempat lain, tanpa mendapatkan masalah karena ruang nama impor tidak ada. Satu-satunya masalah adalah, MS menggunakan ruang nama untuk taksonomi daripada pencegahan tabrakan nama - karena itu, ruang nama terlalu panjang. Juga, jika Anda menghapus namspaces dan menggunakan metode ekstensi, jenis orang yang sama akan mulai mengeluh tentang kode yang tidak dapat dikompilasi. Tidak semua orang menggunakan IDE, jadi lebih baik begini.
Stefan Steiger
3
@JedatKinports: Tidak, hanya injeksi. Meskipun Anda akan menulis metode statis, Anda masih memerlukan konfigurasi. Anda bisa membaca file JSON / YAML secara manual. Tapi itu akan menghilangkan penimpaan, seperti rahasia pengguna atau lainnya (misalnya konfigurasi dari registri).
Stefan Steiger
1
Saya mendapatkan kesalahan: "MyClass memang berisi definisi untuk 'Konfigurasi' ..."
Robert Smith
3
Apa yang dimaksud dengan "this.Configuration" di bagian string koneksi? GetConnectionString (this.Configuration, "DefaultConnection")
MC9000
111

Jawaban yang diposting baik-baik saja tetapi tidak secara langsung menjawab pertanyaan yang sama dengan yang saya miliki tentang membaca dalam string koneksi. Melalui banyak pencarian, saya menemukan cara yang sedikit lebih sederhana untuk melakukan ini.

Di Startup.cs

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

Di pengontrol Anda, tambahkan bidang untuk konfigurasi dan parameter untuk itu pada konstruktor

private readonly IConfiguration configuration;

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

Sekarang nanti dalam kode tampilan Anda, Anda dapat mengaksesnya seperti:

connectionString = configuration.GetConnectionString("DefaultConnection");
Brad Patton
sumber
2
Tidak akan melakukannya seperti itu. Jika Anda bekerja tanpa kerangka entitas, lebih baik Anda mendaftarkan pabrik koneksi sebagai tunggal, misalnya untuk digunakan dengan rapi. Anda kemudian masih dapat mengekspos properti connectionString jika perlu, tetapi saya yakin itu tidak akan diperlukan dalam 99% kasus.
Stefan Steiger
2
Tetapi bagaimana cara mengakses Konfigurasi di Model alih-alih Pengontrol?
Tanmay
2
Semakin banyak saya membaca dan mencoba berbagai hal, semakin saya menyadari bahwa mendapatkan string koneksi adalah pekerjaan besar. Saya hanya mendapatkan nol tidak peduli apa yang saya coba.
MC9000
7
Ya. Terlalu banyak ilmuwan komputer yang membuat buah gantung besar hanya untuk mengucapkan "Halo Dunia". Luar biasa. Entropi itu yang terbaik.
JustJohn
2
@JustJohn: Saya memahami keluhan Anda, tetapi desain yang tepat dapat diuji, dan itu berarti Anda harus meneruskan dependensi di konstruktor, jika tidak, aplikasi / kerangka kerja Anda tidak dapat diuji unit. Ini juga merupakan desain yang tepat, karena Anda dapat mengganti satu komponen dengan yang lain, tanpa harus mengubah banyak kode. Jika Anda tidak ingin meneruskan 100 argumen, Anda juga dapat meneruskan System.IServiceProvider ke dalam kelas, lalu Anda dapat mengambil dependensi di sana. Tetapi sisi lain dari koin ini adalah ini datang dengan kompleksitas tambahan.
Stefan Steiger
18

Lihat tautan untuk info lebih lanjut: 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, mulai 3.1: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1

markokstate
sumber
Mengapa file JSON harus memiliki, ConnectionStringsbukan ConnectionString? Karena ketika saya digunakan ConnectionString, maka kami mendapatkan null.
Vijay
@Vijay Coba gunakan metode yang ditentukan kemudian;) Silakan lihat tautan terlampir.
markokstate
1
Metode ini tampaknya kedaluwarsa pada Microsoft.Extensions.Configuration(3.1.5)
Ju66ernaut
7

Cara yang saya temukan untuk menyelesaikan ini adalah dengan menggunakan AddJsonFile di builder pada Startup (yang memungkinkannya menemukan konfigurasi yang disimpan dalam file appsettings.json) dan kemudian menggunakannya untuk menyetel variabel _config pribadi

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();
    }

Dan kemudian saya dapat mengatur string konfigurasi sebagai berikut:

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

Ini ada di dotnet core 1.1

Alex White
sumber
5
bagaimana cara mengakses _config di kontrol saya?
cerah pada
Dengan menambahkannya ke kontainer DI di ConfigureServices di Startup.cs.
Stefan Steiger
3

ASP.NET Core ( dalam kasus saya 3.1 ) memberi kami suntikan Konstruktor ke Pengontrol , jadi Anda dapat menambahkan konstruktor berikut:

[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")
    }
}

Berikut tampilan appsettings.json:

{
    "ConnectionStrings": {
        "Default": "YOUR_CONNECTION_STRING"
        }
}
antonpv
sumber
0

Ada pendekatan lain. Dalam contoh saya, Anda melihat beberapa logika bisnis di kelas repositori yang saya gunakan dengan injeksi ketergantungan di ASP .NET MVC Core 3.1.

Dan di sini saya ingin mendapatkan connectiongStringlogika bisnis itu karena mungkin repositori lain akan memiliki akses ke database lain sama sekali.

Pola ini memungkinkan Anda dalam repositori logika bisnis yang sama memiliki akses ke database yang berbeda.

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"
  }
}
Pengembang
sumber
-1

saya memiliki perpustakaan akses data yang bekerja dengan inti .net dan kerangka kerja .net.

Triknya ada di proyek inti .net untuk menyimpan string koneksi dalam file xml bernama "app.config" (juga untuk proyek web), dan menandainya sebagai 'salin ke direktori keluaran',

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

ConfigurationManager.ConnectionStrings - akan membaca string koneksi.

    var conn1 = ConfigurationManager.ConnectionStrings["conn1"].ConnectionString;
shaig
sumber
Jika Anda menggunakan .NET Core, yang terbaik adalah mengadopsi pola konfigurasinya daripada memakai sepatu dalam pola .NET Framework.
Simmetric