简体   繁体   中英

azure webjob: Read appSettings.json and inject configuration to TimerTrigger

I have trouble reading configuration values from appSettings.json file in webjob. The webjob uses the following nuget packages:

在此处输入图片说明

I have two settings file in my console application (webjob): appsettings.development.json appsettings.production.json

In the Main method, the webjob is configured as follows:

 static void Main(string[] args)
    {
        var builder = new HostBuilder()
                .ConfigureWebJobs(webJobConfiguration =>
                {
                    webJobConfiguration.AddTimers();
                    webJobConfiguration.AddAzureStorageCoreServices();  
                })
                .ConfigureAppConfiguration((hostingContext, config) =>
                 {
                     var env = hostingContext.HostingEnvironment;
                     Console.WriteLine("hostingContext.HostingEnvironment: " + env.EnvironmentName);
                     config.SetBasePath(Directory.GetCurrentDirectory())
                     .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: false, reloadOnChange: true)
                     .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: false, reloadOnChange: true)
                     .AddEnvironmentVariables().Build();
                 })
                .ConfigureServices((context, serviceCollection) =>
                {
                    serviceCollection.AddSingleton<IConfiguration>(context.Configuration);
                    serviceCollection.AddTransient<SayHelloWebJob>(job => new SayHelloWebJob(context.Configuration));
                })
                .Build();

        builder.Run();
    }

The code for SayHelloWebJob is below:

public class SayHelloWebJob
{
     static IConfiguration _configuration;
    public SayHelloWebJob(IConfiguration config)
    {
        _configuration = config;
        Console.WriteLine("Initialized SayHelloWebJob");
    }

    [Singleton]
    public static void TimerTick([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer)
    {
        Console.WriteLine($"From SayHelloWebJob: Hello at {DateTime.UtcNow.ToString()}");
        var test = _configuration.GetSection("WebJobConfiguration:message").Value;
        Console.WriteLine("Configuration access: message: " + test);
        Console.WriteLine("Configuration access: " + _configuration.GetSection("WebJobConfiguration:api").Value);
        Console.WriteLine("configuration object: "+ _configuration.GetConnectionString("AzureWebJobsStorage"));

    }
}

When I run my webjob, I see that console.writeline logs never output the configurations which I'm trying to read in the TimerTick method.

Questions:

  1. How can I inject the appSettings configuration inside the TimerTick method?
  2. I have two appSettings files - for development & production. How can I make sure the correct file gets loaded during production?

Example appSettings.development.json file below:

{
"connectionStrings": {
    "AzureWebJobsStorage": stringhere",
    "AzureWebJobsDashboard": "stringhere"
},
"WebJobConfiguration": {
    "message": "I'm running locally!",
    "pfuWebApiUrl": "API link here",
    "api": "api here",
    "ApplicationInsights": {
        "InstrumentationKey": "key here"
    }
}

}

My preference is to have all environment configuration checked in as you have and it is definitely possible to load the correct file at runtime based on environment.

First set your config files to "copy to output directory in newer" in the Properties pane in Visual Studio or add this to your csproj:

    <None Update="base.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </None>
    <None Update="prod.settings.json">
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </None>

Now you just need to load the correct configuration at runtime.

        private static IConfigurationRoot GetConfiguration(string basePath)
        {
            string filename = Constants.IsAzureEnvironment ? "prod.settings.json" : "dev.settings.json";

            IConfigurationBuilder configBuilder = new ConfigurationBuilder()
                .SetBasePath(basePath)
                .AddJsonFile("base.settings.json")
                .AddJsonFile(filename);

            return configBuilder.Build();
        }

I get basePath from the executionContext parameter of the azure function

        [FunctionName("Function1")]
        public static async Task<IActionResult> RunAsync([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext context)
        {
            // context.FunctionAppDirectory
            return new OkResult();
        }

I used the Json.NET to read the json file.

This is my json content:

{
   "object": {
      "name": "cwr"
   },
   "others": "123"
}

And this is function.cs code:

 public static void Run([TimerTrigger("0 */1 * * * *")] TimerInfo timer,
        ILogger logger)
    {
        
        JObject jsonData = JObject.Parse(File.ReadAllText(path));

        logger.LogInformation(jsonData["object"]["name"].ToString());
        logger.LogInformation(jsonData["others"].ToString());

    }

And here is output:

在此处输入图片说明

Hope this could help you, if you still have other questions, please let me know.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM