具有Dapper和错误处理功能的ASP Net Core SQL自定义配置提供程序

时间:2019-02-11 02:15:36

标签: asp.net-core asp.net-core-mvc dapper asp.net-core-2.1

我正在设置MVC Web应用程序,以在启动时从我的SQL Azure数据库中提取配置数据。我已经使用这两篇​​文章(MicrosoftMedium)来指导我,但是都没有包括错误处理,我想避免使用任何实体框架引用,因为我正在使用Dapper。到目前为止,我已经将其与下面的代码一起使用,但是我不确定在这种情况下如何处理错误。例如,如果我从SQLConfigurationProvider中的Load方法中删除了try / catch,那么应用程序将在启动时崩溃,但是如果我包含try / catch,则将处理错误并且应用程序将正常启动,但是没有可用的配置数据,因此最终将在尝试访问配置值。正确处理这些错误的最佳方法是什么(即,应用程序仍在加载但显示错误页面/消息)?另外,拥有SQLConfigurationSource是否有任何好处,或者仅仅在SQLConfigurationProvider中创建新的SqlConnection实例是否更有意义?

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; }
}

----更新:但不能完全关闭----

我将异常添加为配置值,然后按如下所示在Startup.cs的Configure方法中进行检查。这有助于确保应用程序在启动时不会崩溃,但是当我引发异常时,即使已经使用 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?}");
    });
}

2 个答案:

答案 0 :(得分:1)

如果没有存储在SQL中的配置,应用程序无法运行,则应移动此代码以获取数据,以更好地管理错误。这样,您将能够向用户显示正确的错误消息并更好地记录它。另一个选择是使用program.cs中的try / catch块,并且假定没有SQL驱动的配置不会破坏启动项目,但会破坏应用程序的使用。在这种情况下,您将已经在启动时进行了错误管理,并且可以为此显示一个功能错误页面。

This link将为您提供有关startup / program.cs错误处理的一些视图

答案 1 :(得分:0)

您应该配置一个自定义错误处理页面,请阅读以下内容。这很容易做到 Custom Error Page .net Core