Я настраиваю свое веб-приложение MVC для загрузки данных конфигурации из базы данных SQL Azure при запуске.Я использовал эти две статьи ( Microsoft , Средняя ), чтобы ориентировать меня, но ни одна из них не включает обработку ошибок, и я хочу избежать любых ссылок на Entity Framework, поскольку я использую Dapper.До сих пор я работал с приведенным ниже кодом, но я не уверен, как обрабатывать ошибки в этом сценарии.Например, если я удаляю try / catch из метода Load в SQLConfigurationProvider, то приложение аварийно завершает работу при запуске, но если я включаю try / catch, тогда ошибка обрабатывается, и приложение запускается нормально, но данные конфигурации недоступны, поэтому в конечном итоге произойдет сбой, когдапытаясь получить доступ к значению конфигурации.Каков наилучший способ корректно обработать эти ошибки (т.е. приложение все еще загружается, но вместо этого отображает страницу / сообщение об ошибке)?Также есть ли какая-то польза от наличия SQLConfigurationSource или было бы более целесообразно просто создать вместо него новый экземпляр SqlConnection внутри SQLConfigurationProvider?
Program.cs
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)
.UseSetting(WebHostDefaults.DetailedErrorsKey, "true")
.UseApplicationInsights()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.AddSQLConfiguration(); // Custom configuration here
})
.UseStartup<Startup>();
}
ConfigurationExtensions.cs
public static class ConfigurationExtensions
{
public static IConfigurationBuilder AddSQLConfiguration(this IConfigurationBuilder builder)
{
var connectionString = builder.Build().GetConnectionString("DefaultConnection");
return builder.Add(new SQLConfigurationSource(connectionString));
}
}
SQLConfigurationSource.cs
public class SQLConfigurationSource : IConfigurationSource
{
private readonly SqlConnection _connection;
public SQLConfigurationSource(string connectionString)
{
_connection = new SqlConnection(connectionString);
}
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new SQLConfigurationProvider(_connection);
}
}
SQLConfigurationProvider.cs
public class SQLConfigurationProvider : ConfigurationProvider
{
private readonly SqlConnection _connection;
public SQLConfigurationProvider(SqlConnection connection)
{
_connection = connection;
}
public override void Load()
{
try
{
var model = _connection.Query<SQLConfigurationModel>("sp does not exist for example", commandType: CommandType.StoredProcedure);
Data = model.ToDictionary(x => x.Property, x => x.Value);
}
catch (Exception ex)
{
// WHAT TO DO HERE?
}
}
}
public class SQLConfigurationModel
{
public string Property { get; set; }
public string Value { get; set; }
}
---- ОБНОВЛЕНИЕ: ЗАКРЫТЬ, НО НЕ ТАМ ТАМ ----
Я добавил исключение в качестве значения конфигурации, которое затем проверяю в методе Configure при запуске.cs согласно ниже.Это помогает гарантировать, что приложение не аварийно завершает работу при запуске, но когда я генерирую исключение, оно не перенаправляется в представление «Ошибка», даже если обработчик исключения уже настроен с app.UseExceptionHandler ("/ Home / Error")
// Inside SQLConfigurationProvider
public override void Load()
{
try
{
var model = _connection.Query<SQLConfigurationModel>("sp does not exist for example", commandType: CommandType.StoredProcedure);
Data = model.ToDictionary(x => x.Property, x => x.Value);
}
catch (Exception ex)
{
Data.Add("ConfigurationLoadException", ex.Message);
}
}
// Inside Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseExceptionHandler("/Home/Error");
// Check for custom config exception
string configurationLoadException = Configuration["ConfigurationLoadException"];
if (configurationLoadException.Length > 0)
{
throw new Exception("Configuration Failed: " + configurationLoadException);
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}