web-dev-qa-db-fra.com

les clés personnalisées dans appSettings.json ne fonctionnent pas dans ASP.NET Core 2.0

J'ai ajouté une clé de section CustomSettings dans appSettings.json dans un projet ASP.NET Core:

{
  "ConnectionStrings": {
    "DefaultConnectionString": "Data Source=..."
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "CustomSettings": {
    "Culture": "es-CO"
  }
}

Je n'ai pas été en mesure de charger la clé de culture dans le contrôleur suivant:

public AccountController(
            UserManager<ApplicationUser> userManager,
            SignInManager<ApplicationUser> signInManager,
            IEmailSender emailSender,
            ILogger<AccountController> logger,
            IConfiguration configuration)
{
   Response.Cookies.Append(
                    CookieRequestCultureProvider.DefaultCookieName,
                    CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(configuration.GetSection("CustomSettings")["Culture"])),
                    new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) }
            );
}

Peu importe que je suive, ils renvoient toujours NULL: Configuration.GetSection ("CustomSettings") ["Culture"]; Configuration.GetSection ("CustomSettings"). GetValue ("Culture");

J'ai essayé l'aide basée sur ASP.NET Core: Guide étape par étape pour accéder à appsettings.json dans un projet Web et une bibliothèque de classes et j'ai créé la classe CustomSettings avec la propriété de chaîne Culture et l'injection dans Startup comme suit:

        // Load Custom Configuration from AppSettings.json
        services.Configure<Models.CustomSettings>(Configuration.GetSection("CustomSettings"));

En accédant par injection à IOptions customSettings, la valeur de CustomSettings.Value.Culture renvoie NULL.

Première question: Qu'est-ce que je fais mal ou qu'est-ce qui manque?

Deuxième question: ¿Pourquoi suivre Index dans HomeController lève une exception?

public class HomeController : Controller
{
   public IActionResult Index(IConfiguration configuration)
   {
   }
}

Exception:

Une exception non gérée s'est produite lors du traitement de la demande . InvalidOperationException: impossible de créer une instance de type 'Microsoft.Extensions.Options.IOptions`1 [[OmniMerchant.Models.CustomSettings, OmniMerchant, Version = 1.0.0.0, Culture = neutre , PublicKeyToken = null]] '. Les types complexes liés au modèle ne doivent pas être des types abstraits ou de valeur et doivent avoir un constructeur sans paramètre.

Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.CreateModel (ModelBindingContext bindingContext)

Troisième question: Je dois définir Culture à partir de Démarrage pour toutes les applications en arrière-plan, en fonction de la propriété Culture sur appSettings.json. J'ai lu la documentation MSDN , mais je n’ai pas réussi à atteindre cet objectif. Comment puis-je obtenir des résultats? ce?

Merci

6

Commencez par créer le modal correspondant à la section Appsetting

public class CustomSettings
{
    public string Culture { get; set; }
}

Puis enregistrez-le dans la méthode ConfigureServices dans Startup.cs

services.Configure<CustomSettings>(Configuration.GetSection("CustomSettings"));

Puis injectez-le en utilisant IOptions à la place

AccountController(IOptions<CustomSettings> settings)
{
    _settings = settings.Value;
}
7
Marcus Höglund
  1. Pourquoi les valeurs des sections de configuration sont nulles?

Par défaut, il existe deux fichiers de configuration. Pour la version Release et un pour le débogage. Avez-vous vérifié que vous aviez bien édité le bon (probablement appsettings.Development.json)

  1. Pourquoi DI ne fonctionne pas.

Dans .NET Core, vous pouvez utiliser l’ID de deux manières. En l'injectant en constructeur ou directement en méthode. Dans la deuxième option, vous devez utiliser l'attribut spécial [FromServices]

4
Thowk

Dans les propriétés de votre application -> Section de débogage -> Variables d'environnement

Si ceci est défini ASPNETCORE_ENVIRONMENT: Développement

Il utilisera appsettings.Development.json

4
Ryan Dobbs

J'ai eu des problèmes pour lire à partir de différents fichiers de configuration jusqu'à ce que je les ajoute spécifiquement dans le constructeur de démarrage, comme ci-dessous:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json")                //***
        .AddJsonFile("appsettings.development.json")    //***
        .AddEnvironmentVariables();

        Configuration = builder.Build();
}
2
Mircea Nemteanu

TL: DR; Votre fichier appsettings.json doit se trouver dans le même répertoire de travail que votre fichier dll.

Vous devez vous assurer que vous exécutez l'application à partir de son répertoire de travail.

Par exemple, si vos dll sont générées dans le dossier bin, les opérations suivantes ne fonctionneront pas:

cd bin
dotnet run app.dll

Parce que le fichier appsettings.json ne se trouve pas dans le même dossier que la dll à partir de laquelle vous exécutez.

Toutefois, si vous êtes dans le répertoire dans lequel se trouve le fichier appsettings.json, le répertoire de travail actuel sera défini et ce fichier sera lu.

dotnet run bin/app.dll

Si vous utilisez VS Code launch.json, vous pouvez définir la propriété cwd pour atteindre cet objectif.

1
Darbio

C’est un bogue je pense mais vous pouvez probablement le résoudre en définissant manuellement "HostingEnvironment.ContentRootPath".

Essayez d'ajouter le code suivant dans la méthode de démarrage dans Startup.cs:

if (env.EnvironmentName== "Production")
{
    env.ContentRootPath = System.IO.Directory.GetCurrentDirectory();
}

ou chemin de code dur comme ceci:

if (env.EnvironmentName == "Production")
{
    env.ContentRootPath = "/var/aspnetcore/...";
}

Par exemple, si vos fichiers se trouvent dans "/var/aspnetcore/my_ASP_app ", la méthode de démarrage devrait ressembler à ceci:

public Startup(IHostingEnvironment env)
{
    if (env.EnvironmentName== "Production")
    {
        //env.ContentRootPath = "/var/aspnetcore/my_ASP_app";
        env.ContentRootPath = System.IO.Directory.GetCurrentDirectory();
    }
    //env.ContentRootPath = System.IO.Directory.GetCurrentDirectory();//you can write this line outside of IF block.
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile("appsettings.Production.json", optional: true, reloadOnChange: true);

    Configuration = builder.Build();

}

Il vaut mieux utiliser Directory.GetCurrentDirectory () au lieu de coder en dur.

Cela a fonctionné pour moi dans Linux Ubuntu avec nginx , mais je ne sais pas si cela s’applique à votre environnement.

0
Mostafa.A