วิธีอ่านสตริงการเชื่อมต่อใน. NET Core?


112

ฉันต้องการอ่านเพียงสตริงการเชื่อมต่อจากไฟล์การกำหนดค่าและสำหรับสิ่งนี้ให้เพิ่มไฟล์ที่มีชื่อ "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 ได้อย่างไร


คำตอบ:


103

คุณสามารถทำได้ด้วยวิธีการขยาย 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

@ James Wilkins: ข้อกังวลที่ถูกต้องมาก อย่างไรก็ตามฉันชอบสัญกรณ์นี้มากกว่าการใช้มันเป็นวิธีการขยาย - วิธีนี้ทำให้ฉันรู้ว่ากำลังทำอะไรอยู่ที่ไหนและสามารถคัดลอกวางจากที่ 1 ไปยังอีกที่หนึ่งได้โดยไม่เกิดปัญหาเนื่องจากไม่มีเนมสเปซการนำเข้า ปัญหาเดียวคือ MS ใช้เนมสเปซสำหรับอนุกรมวิธานแทนการป้องกันการชนกันของชื่อ - ด้วยเหตุนี้เนมสเปซจึงยาวเกินไป นอกจากนี้หากคุณลบ Namspaces และใช้วิธีการขยายคนประเภทเดียวกันจะเริ่มบ่นเกี่ยวกับรหัสที่ไม่รวบรวม ไม่ใช่ทุกคนที่ใช้ IDE ดังนั้นวิธีนี้จะดีกว่า
Stefan Steiger

3
@JedatKinports: ไม่ฉีดอย่างเดียว แม้ว่าคุณจะเขียนวิธีการแบบคงที่ แต่คุณก็ยังต้องมีการกำหนดค่า คุณสามารถอ่านไฟล์ JSON / YAML ด้วยตนเองได้ แต่นั่นจะกำจัดการเขียนทับเช่น usersecrets หรืออื่น ๆ (เช่นการกำหนดค่าจากรีจิสทรี)
Stefan Steiger

1
ฉันได้รับข้อผิดพลาด: "MyClass มีคำจำกัดความสำหรับ" Configuration "... "
Robert Smith

3
"this.Configuration" หมายถึงอะไรในส่วนสตริงการเชื่อมต่อ GetConnectionString (this.Configuration, "DefaultConnection")
MC9000

115

คำตอบที่โพสต์นั้นใช้ได้ แต่ไม่ได้ตอบคำถามเดียวกันกับที่ฉันมีเกี่ยวกับการอ่านในสตริงการเชื่อมต่อโดยตรง จากการค้นหามากมายฉันพบวิธีที่ง่ายกว่านี้เล็กน้อย

ใน 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
คงไม่ทำแบบนั้นหรอก หากคุณทำงานโดยไม่มีกรอบของเอนทิตีคุณควรลงทะเบียนโรงงานการเชื่อมต่อเป็นซิงเกิลตันเช่นใช้กับ dapper จากนั้นคุณยังสามารถเปิดเผยคุณสมบัติ connectionString ได้หากต้องการ แต่ฉันพนันได้เลยว่ามันไม่จำเป็นใน 99% ของกรณี
Stefan Steiger

2
แต่จะเข้าถึง Configuration ใน Models แทน Controller ได้อย่างไร?
Tanmay

2
ยิ่งฉันอ่านและลองทำสิ่งต่างๆมากเท่าไหร่ฉันก็ยิ่งรู้ว่าการมีสายอักขระการเชื่อมต่อเป็นงานหลัก ฉันได้ค่าว่างไม่ว่าฉันจะพยายามทำอะไรก็ตาม
MC9000

7
ใช่. นักวิทยาศาสตร์คอมพิวเตอร์จำนวนมากเกินไปที่สร้างผลไม้แขวนสูงขนาดใหญ่เพียงเพื่อพูดว่า "สวัสดีชาวโลก" เหลือเชื่อ. เอนโทรปีที่ดีที่สุด
JustJohn

2
@JustJohn: ฉันเข้าใจความคับข้องใจของคุณ แต่การออกแบบที่เหมาะสมนั้นสามารถทดสอบได้และนั่นหมายความว่าคุณต้องผ่านการอ้างอิงในตัวสร้างมิฉะนั้นแอปพลิเคชัน / เฟรมเวิร์กของคุณจะไม่สามารถทดสอบหน่วยได้ นี่เป็นการออกแบบที่เหมาะสมเช่นกันเนื่องจากคุณสามารถแทนที่ส่วนประกอบหนึ่งด้วยอีกส่วนหนึ่งได้โดยไม่ต้องเปลี่ยนรหัสมากนัก หากคุณไม่ต้องการส่งผ่านอาร์กิวเมนต์ 100 รายการคุณสามารถส่ง System.IServiceProvider ไปยังคลาสจากนั้นคุณสามารถดึงการอ้างอิงที่นั่นได้ แต่อีกด้านหนึ่งของเหรียญคือสิ่งนี้มาพร้อมกับความซับซ้อนที่เพิ่มเข้ามา
Stefan Steiger

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

แก้ไข: 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 ในตัวสร้างที่ Startup (ซึ่งช่วยให้สามารถค้นหาการกำหนดค่าที่เก็บไว้ในไฟล์ 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 core 1.1


5
ฉันจะเข้าถึง _config ในการควบคุมของฉันได้อย่างไร
แดดจัด

โดยเพิ่มไปยังคอนเทนเนอร์ DI ใน ConfigureServices ใน Startup.cs
Stefan Steiger

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ใช้ตรรกะทางธุรกิจนั้นเพราะที่เก็บอื่นอาจเข้าถึงฐานข้อมูลอื่นได้เลย

รูปแบบนี้ช่วยให้คุณในที่เก็บตรรกะทางธุรกิจเดียวกันสามารถเข้าถึงฐานข้อมูลที่แตกต่างกันได้

ค#

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

0

ใน 3.1 มีส่วนที่กำหนดไว้แล้วสำหรับ "ConnectionStrings"

System.Configuration.ConnnectionStringSettings

กำหนด :

  "ConnectionStrings": {
    "ConnectionString": "..."
  }

ลงทะเบียน :

public void ConfigureServices(IServiceCollection services)
{
     services.Configure<ConnectionStringSettings>(Configuration.GetSection("ConnectionStrings"));
}

ฉีด :

public class ObjectModelContext : DbContext, IObjectModelContext
{

     private readonly ConnectionStringSettings ConnectionStringSettings;

    ...

     public ObjectModelContext(DbContextOptions<ObjectModelContext> options, IOptions<ConnectionStringSettings> setting) : base(options)
    {
          ConnectionStringSettings = setting.Value;
    }

    ...
}

ใช้ :

   public static void ConfigureContext(DbContextOptionsBuilder optionsBuilder, ConnectionStringSettings connectionStringSettings)
    {
        if (optionsBuilder.IsConfigured == false)
        {
            optionsBuilder.UseLazyLoadingProxies()
                          .UseSqlServer(connectionStringSettings.ConnectionString);
        }
    }

-1

ฉันมีไลบรารีการเข้าถึงข้อมูลที่ใช้ได้กับทั้ง. net core และ. net framework

เคล็ดลับอยู่ในโครงการ. net core เพื่อเก็บสตริงการเชื่อมต่อไว้ในไฟล์ 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
Simmetric

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.