79 votes

Obtenez ConnectionString à partir de appsettings.json au lieu d'être codé en dur dans l'application .NET Core 2.0

J'ai la classe suivante dans NET Core2.0 App.

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

Cela est nécessaire en Core 2.0 avec la migration de la Base de données n'existe pas et doit être créé lorsque vous exécutez la mise à jour de la base de données.
Impossible de créer des migrations après la mise à jour ASP.NET Core 2.0

Je voudrais ne pas avoir ConnectionString dans 2 endroits(ici et dans appsettings.json), mais uniquement dans .json j'ai donc essayé de remplacer

"Server=localhost;Database=DbName;Trusted_Connection=True;MultipleActiveResultSets=true"

avec

ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString

mais cela ne fonctionne pas, j'obtiens une valeur null.

Mise à JOUR 1:
Juste à noter que l'ajout de façon explicite .json n'est pas necessery en Base 2 de sorte que le problème n'est pas avec le fichier.
https://andrewlock.net/exploring-program-and-startup-in-asp-net-core-2-preview1-2/

Mise à JOUR 2:
Aussi, je suis déjà à l'aide de Configuration pour l'envoi de ConnectionString de .json au Contexte:

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

Mais je ne peux pas l'utiliser pour ToDoContextFactory car il n'a pas de Configuration, et ToDoContextFactory est utilisé par les migrations ainsi, l'Application ne fonctionne pas du tout.

SOLUTION: Basé sur la réponse de @JUR je l'ai fait travailler comme ceci:

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

109voto

JRB Points 709

ÉTAPE 1: inclure les éléments suivants dans OnConfiguring ()

     protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        IConfigurationRoot configuration = new ConfigurationBuilder()
            .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
            .AddJsonFile("appsettings.json")
            .Build();
        optionsBuilder.UseSqlServer(configuration.GetConnectionString("DefaultConnection"));
    }
 

ÉTAPE 2: Créer appsettings.json:

   {
    "ConnectionStrings": {       
      "DefaultConnection": "Server=YOURSERVERNAME; Database=YOURDATABASENAME; Trusted_Connection=True; MultipleActiveResultSets=true"        
    } 
  }
 

ÉTAPE 3: Copiez le fichier appsettings.json dans le répertoire approprié.

   Hard copy appsettings.json.config to the directory specified in the AppDomain.CurrentDomain.BaseDirectory directory. 
  Use your debugger to find out which directory that is.        
 

Hypothèse: vous avez déjà inclus le package Microsoft.Extensions.Configuration.Json (récupérez-le auprès de Nuget) dans votre projet.

20voto

RGudkov Points 93

Dans ASPNET Core, vous le faites en Startup.cs

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

où votre connexion est définie en appsettings.json

 {
  "ConnectionStrings": {
    "BloggingDatabase": "..."
  },
}
 

Exemple de MS docs

5voto

Johan Herstad Points 413

Que diriez-vous de le passer comme injection dp dans cette classe? dans ConfigureServices:

 services.Configure<MyOptions>(Configuration);
 

Créer une classe pour contenir des chaînes JSON:

 public class MyOptions
{
    public MyOptions()
    {

    }
    public string Option1 { get; set; }
    public string Option2 { get; set; }
}    
 

Ajouter des chaînes au fichier json:

 "option1": "somestring",
"option2": "someothersecretstring"
 

Dans les classes qui ont besoin de ces chaînes, passez en tant que constructeur:

 public class SomeClass
{
 private readonly MyOptions _options;

    public SomeClass(IOptions<MyOptions> options)
    {
        _options = options.Value;           
    }    

 public void UseStrings()
 {
   var option1 = _options.Option1;
    var option2 = _options.Option2;
 //code
 }
}
 

4voto

Erikest Points 1493

Il est en fait un modèle par défaut que vous pouvez employer pour atteindre ce résultat sans avoir à mettre en oeuvre IDesignTimeDbContextFactory et de n'importe quel fichier de configuration de la copie.

Il est détaillé dans ce document, qui aborde également les autres façons dont le cadre tentera d'instancier votre DbContext au moment de la conception.

En particulier, vous tirer parti d'une nouvelle crochet, dans ce cas, une méthode statique de la forme public static IWebHost BuildWebHost(string[] args). La documentation implique le contraire, mais cette méthode peut vivre dans n'importe quelle classe de maisons de votre point d'entrée (voir la src). La mise en œuvre de cette partie de l'orientation dans le 1.x à 2.x document de migration et ce n'est pas tout à fait évident en regardant le code, c'est que l'appel à l' WebHost.CreateDefaultBuilder(args) est, entre autres choses, la connexion de votre configuration par défaut dans le modèle que le démarrage de nouveaux projets avec. C'est tout vous avez besoin pour obtenir la configuration pour être utilisé par le moment de la conception des services comme les migrations.

Voici plus de détails sur ce qu'il se passe sur fond de lui, il y a:

Lors de l'ajout d'une migration, lorsque le cadre de tentatives pour créer votre DbContext, c' premier ajoute tout IDesignTimeDbContextFactory des implémentations qu'il trouve à une collection de usine de méthodes qui peuvent être utilisées pour créer votre contexte, il devient votre configuration de services par l'intermédiaire de la statique crochet discuté plus tôt et semble pour tout types de contexte enregistré avec un DbContextOptions (ce qui arrive dans votre Startup.ConfigureServices lorsque vous utilisez AddDbContext ou AddDbContextPool) et ajoute ceux des usines. Enfin, il regarde au travers de l'assemblée pour n'importe quel DbContext les classes dérivées et crée une usine méthode qui appelle simplement Activator.CreateInstance final je vous salue marie.

L'ordre de priorité que le framework utilise est le même que ci-dessus. Ainsi, si vous avez IDesignTimeDbContextFactory mis en œuvre, il remplace le crochet mentionnés ci-dessus. Pour les scénarios les plus courants, vous n'aurez pas besoin d' IDesignTimeDbContextFactory.

0voto

Jonathan Kittell Points 2559

Vous pouvez également le faire dans ASP.NET Core 2 en définissant la chaîne de connexion dans votre fichier appSettings.json . Ensuite, dans votre Startup.cs vous spécifiez la chaîne de connexion à utiliser.

appSettings.json

 {
    "connectionStrings": {
        "YourDBConnectionString": "Server=(localdb)\\mssqllocaldb;Database=YourDB;Trusted_Connection=True"
    }
}
 

Startup.cs

 public static IConfiguration Configuration { get; private set;}

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}
var connectionString = Configuration["connectionStrings:YourDBConnectionString"];
services.AddDbContext<YourDbContext>(x => x.UseSqlServer(connectionString));
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X