configuration.getValue или configuration.getsection всегда возвращает ноль - PullRequest
0 голосов
/ 29 декабря 2018

Я новичок в .Net Core и пытаюсь получить значение из файла appsettings.json, но я упустил что-то очень простое.Пожалуйста, дайте мне знать, что я сделал неправильно ... Вот код ...

Program.cs

 WebHost.CreateDefaultBuilder(args)
 .ConfigureAppConfiguration((hostingContext, config) =>
 {
      config.SetBasePath(Directory.GetCurrentDirectory());
 })

Startup.cs

public IConfiguration Configuration { get; private set; }
public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
}

Контроллер веб-API

private readonly IConfiguration config;

public EmailController(IConfiguration configuration)
{
    if (configuration != null)
    {
        config = configuration;
    }
}

Метод действия

var emailTemplatesRelativePath = config.GetSection("EmailSettings");
var email = config.GetValue<string>("Email");

Обе вышеуказанные строкивозвращают нулевые значения для GetSection и GetValue

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Trace",
      "Microsoft": "Information"
    }
  },
  "ConnectionStrings": {
    "FCRContext": "server=xxx;database=xxx;user id=xxx;password=xxx"
  },
  "AllowedHosts": "*",
  "EmailSettings": {
    "EmailTemplatesPath": "EmailTemplates"
  },
  "Email": "aa@aa.com"
}

Ответы [ 5 ]

0 голосов
/ 18 мая 2019

В то время как другие решили эту проблему, если вы хотите оставить код службы запуска как есть, просто измените свой контроллер Web API на следующее:

private readonly EmailSettings _emailSettings;

public EmailController(IOptions<EmailSettings> emailSettings)
{
    _emailSettings = emailSettings.Value;
}

Акцент сделан на .Значение .Вот почему ваш код возвращает ноль.Я бы также предложил изменить program.cs обратно на его настройки по умолчанию.И чтобы использовать это в методе действия, просто сделайте следующее:

_email.settings.EmailTemplatesPath

И последнее: убедитесь, что структура вашего класса EmailSettings точно такая же, как у вашего json.

0 голосов
/ 03 января 2019

При размещении в процессе внутри IIS (или IIS Express), Directory.GetCurrentDirectory() вернет другой путь к тому, который возвращается при запуске вне процесса .Вплоть до ASP.NET Core 2.1 хостинг на основе IIS всегда был вне процесса, но в ASP.NET Core 2.2 появилась возможность запускать в процессе (что по умолчанию используется при создании нового проекта).

При запуске вне процесса Directory.GetCurrentDirectory() возвращает путь к самому приложению ASP.NET Core, тогда как при запуске внутри процесса он возвращает путь к IIS (или IIS Express, например, «C: \».Program Files \ IIS Express ").

От вашего вопроса соответствующий код:

WebHost.CreateDefaultBuilder(args)
    .ConfigureAppConfiguration((hostingContext, config) =>
    {
        config.SetBasePath(Directory.GetCurrentDirectory());
    })

Здесь, перед тем как позвонить на SetBasePathIConfigurationBuilder уже настроен для использования правильного пути.Ваш звонок переопределяет этот путь, устанавливая его, например, в «C: \ Program Files \ IIS Express».С этим переопределенным базовым путем ваши файлы appsettings.json и др. Больше не будут найдены, так как они не живут, например, в "C: \ Program Files \ IIS Express", и поэтому конфигурация не загружается изэти файлы.

Решение состоит в том, чтобы просто удалить ваш вызов на ConfigureAppConfiguration, чтобы базовый путь не был переопределен.Я понимаю, что вы уже обнаружили это, но я хотел убедиться, что у вас есть объяснение того, что здесь происходит не так.

0 голосов
/ 29 декабря 2018

Вы допустили простую ошибку и забыли добавить «Email» в «EmailSettings».Обновите ваш json, как показано ниже, и получите письмо с config.GetSection("EmailSettings")["Email"];

"EmailSettings": {
    "EmailTemplatesPath": "EmailTemplates",
    "Email": "aa@aa.com"
  },

Надеюсь, что это решит вашу проблему.

Редактировать:

Есливы хотите получить эти значения из наборов приложений во что угодно, кроме запуска, вы должны загрузить эти значения конфигурации в класс параметров, а затем внедрить соответствующий экземпляр IOptions в конструктор метода, в котором вы хотите использовать эти параметры.Для этого смотрите мой ответ здесь .

0 голосов
/ 30 декабря 2018

Program.cs

public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();

        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
             .UseStartup<Startup>();
    }

Startup.cs:

public partial class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
        {
            app.UseMvcWithDefaultRoute();
        }
    }

Класс контроллера

enter image description here

Вам необходимо использовать метод Bind (), чтобы получить значение из раздела.

EmailSetting option = new EmailSetting();
            //You need to bind the section with data model, 
            //it will automatically map config key to property of model having same name
            config.GetSection("EmailSettings").Bind(option);

            //Alternative to this you can read nested key using below syntax
            var emailTemplatesPath = config["EmailSettings:EmailTemplatesPath"];
            var emailInEmailSettings = config["EmailSettings:Email"];
            // If email key is not nested then you can access it as below
            var email = config.GetValue<string>("EmailOutside");

Модель настройки электронной почты: - (Свойствоимя должно совпадать с ключом конфигурации)

public class EmailSetting
    {
        public string EmailTemplatesPath { get; set; }
        public string Email { get; set; }
    }

Appsetting.json: -

    {
       "AllowedHosts": "*",
        "EmailSettings": {
            "EmailTemplatesPath": "EmailTemplates",
            "Email": "aa@aa.com"
          },
          "EmailOutside": "aa@aa.com"
        }
0 голосов
/ 29 декабря 2018

Доступ к конфигурации в контроллере работает немного иначе, чем в Startup.cs.Я сделал это некоторое время назад, просто следуйте этим шагам:

Поместите всю конфигурацию, к которой вы хотите получить доступ в вашем контроллере, в один раздел, например "EmailSettings":

appsettings.json

{
  "EmailSettings": {
    "EmailTemplatesPath": "EmailTemplates",
    "Email": "aa@aa.com"
  }
}

Затем создайте в своем проекте веб-API класс с именем EmailSettings.cs:

EmailSettings.cs

public class EmailSettings
{
    public string EmailTemplatesPath { get; set; }
    public string Email { get; set; }
}

Затем привяжите свои значения Config к экземпляру класса EmailSettings в Startup.cs и добавьте этот объект в контейнер внедрения зависимостей:

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    ...
    EmailSettings emailSettings = new EmailSettings();
    Configuration.GetSection("EmailSettings").Bind(emailSettings);
    services.AddSingleton(emailSettings);
}

Теперь вы можете запросить свою конфигурацию в контроллере Api, просто добавив ее в конструктор следующим образом:

Контроллер веб-API

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    EmailSettings _emailSettings;

    public ValuesController(EmailSettings emailSettings)
    {
        _emailSettings = emailSettings;
    }
....
}

Просто повторите попыткув моем текущем проекте (.NET Core 2.2 Web Api), и он работал.Я поместил точку останова в конструктор ValuesController, и объект _emailSettings содержал значения из файла appsettings.json.Вы должны быть в состоянии просто скопировать и вставить это!Повеселись!:)

...