I am creating a scheduled Task in ASP.NET Core WebAPI. I am trying to get 5 URLs from appsettings.json which are not in a section, just in the root of appsettings.json. If I hardcode the strings in the Final class (mentioned in the last of this question), it works fine, but
This is my Program.cs:
public static void Main(string[] args)
{
var configuration = GetConfiguration();
var host = BuildWebHost(configuration, args);
host.Run();
//CreateWebHostBuilder(configuration,args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(IConfiguration _configuration,string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseConfiguration(_configuration);
private static IConfiguration GetConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
return builder.Build();
}
Following is my Startup.cs:
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<ScheduledTaskSettings>(Configuration);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton<IOrderSchedulerTask, OrderSchedulerTask>();
services.AddScheduler((sender, args) =>
{
Console.Write(args.Exception.Message);
args.SetObserved();
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
I have also created ScheduledTaskSettings.cs with the following class. The string names are identical to the names in appsettings.json.
public class ScheduledTaskSettings
{
public string ConnectionString { get; set; }
public string CustomersApiEndpointUrl { get; set; }
public string SubscriptionsApiEndpointUrl { get; set; }
public string ProductsApiEndpointUrl { get; set; }
public string SubscribersApiEndpointUrl { get; set; }
public string CronScheduleTime { get; set; }
}
I have an interface IOrderSchedulerTask.cs:
public interface IOrderSchedulerTask
{
string Schedule { get; }
Task ExecuteAsync(CancellationToken cancellationToken);
}
And the final class OrderSchedulerTask.cs
public class OrderSchedulerTask : IOrderSchedulerTask
{
// Implementing IOrderScheduler
// Scheduled for every one minute
public string Schedule => "*/1 * * * *";
public async Task ExecuteAsync(CancellationToken cancellationToken)
{
var httpClient = new HttpClient();
OrderScheduler.GenerateOrders();
}
}
public class OrderScheduler
{
public static ScheduledTaskSettings _scheduledTaskSettngs;
public OrderScheduler(ScheduledTaskSettings scheduledTaskSettings)
{
_scheduledTaskSettngs = scheduledTaskSettings;
}
private static string CustomerApiUrl = _scheduledTaskSettngs.CustomersApiEndpointUrl;
private static string SubscriptionApiUrl = _scheduledTaskSettngs.SubscriptionsApiEndpointUrl;
private static string CatalogApiUrl = _scheduledTaskSettngs.ProductsApiEndpointUrl;
private static string SubscriberUrl = _scheduledTaskSettngs.SubscribersApiEndpointUrl;
private static string _connectionString = _scheduledTaskSettngs.ConnectionString;
private static List<Customer> customers = null;
private static List<Subscription> subscriptions = null;
private static List<CatalogItem> products = null;
private static List<Subscriber> subscribers = null;
private static List<Order> orders = new List<Order>();
/// <summary>
/// Generate the orders for next day
/// </summary>
public static async void GenerateOrders()
{
// Get Customers Data
GetCustomers();
//Get Subscription Data
GetSubscriptions();
//Get Products Data
GetProducts();
//Get Subscribers Data
GetSubscribers();
var order = new Order();
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
foreach (var item in subscriptions)
{
//
}
}
}
private static async void GetCustomers()
{
//Uses CustomerApiUrl String
}
private static async void GetSubscriptions()
{
//Uses SubscriptionApiUrl String
}
private static async void GetProducts()
{
//Uses CatalogApiUrl String
}
private static async void GetSubscribers()
{
//Uses SubscriberUrl String
}
}
If I hardcode the strings, it works fine, but it throws the following exception when I use the configuration method:
Unhandled Exception:
Unhandled Exception:
Unhandled Exception:
Unhandled Exception: System.TypeInitializationException: The type initializer for
'Ordering.ScheduledTask.Tasks.OrderScheduler' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at Ordering.ScheduledTask.Tasks.OrderScheduler..cctor() in ... OrderSchedulerTask.cs Line 22
Can someone please guide me through about what should I be doing to correct it.