天天看點

asp.net core配置驗證

作者:桂素偉

在開發asp.net core時,通常會在appsettings.json中配置資訊,這些資訊都是以一個json的格式存儲,在程式中通過Options的方式來綁定實體類使用,如下面的APIConfig和實體類。

配置檔案:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  
  "APIConfig": {
    "TimeOut": 2000,
    "Category": "Small",
    "Max": 1.5
  }
}           

APIConfig實體類:

public class APIConfig
{
    public int TimeOut { get; set; }
    public string? Category { get; set; }
    public double Max { get; set; }
}
public enum Category
{
    None,
    Large,
    Small,
    Middle
}           

配置裸奔是有相當風險的,每個配置項都應該特定的含義和範圍,當不合規配置随着系統啟動,悄悄地進入服務狀态時,就相當埋了一顆雷,肯定有人會在某時間踩上,爆掉,形成一次生産事幫。為了把這個風險消除掉,那就要給這些配置設定個圍欄——即驗證。

可以在服務啟動時,添加Valdate來驗證配置檔案。首先用Bind方式取出要驗證的配置實體,再次就是用Validate方法逐個驗證為了把問題盡早暴露,當然,怎麼驗證,驗證那些屬性,自行決定。

using Microsoft.Extensions.Options;
using System.ComponentModel.DataAnnotations;


var builder = WebApplication.CreateBuilder(args);
builder.Services
    .AddOptions<APIConfig>()
    .Bind(builder.Configuration.GetSection(nameof(APIConfig)))
    .Validate(c =>
    {
        return c.TimeOut > 0 && c.TimeOut <= 1000 && c.Max >= -1.5 && c.Max <= 1.5 && Enum.TryParse<Category>(c.Category, true, out Category o);
    },"APIConfig配置有誤!")
    .ValidateOnStart();
var app = builder.Build();
app.MapGet("/apiconfig", (IOptions<APIConfig> options) =>
{
    return options.Value;
});
app.Run();           

其實驗證在.net很普及,使用的是DataAnnotations,當然,這裡也不例外,可以在實體類上添加具體的驗證規則,這裡就不展開了。代碼如下:

using Microsoft.Extensions.Options;
using System.ComponentModel.DataAnnotations;


var builder = WebApplication.CreateBuilder(args);
builder.Services
    .AddOptions<APIConfig>()
    .Bind(builder.Configuration.GetSection(nameof(APIConfig)))
    .ValidateDataAnnotations()
    .ValidateOnStart();
var app = builder.Build();
app.MapGet("/apiconfig", (IOptions<APIConfig> options) =>
{
    return options.Value;
});
app.Run();


public class APIConfig
{
    [Range(0,1000)]
    public int TimeOut { get; set; }
    [EnumDataType(typeof(Category))]
    public string? Category { get; set; }
    [Range(-1.5, 1.5)]
    public double Max { get; set; }
}


public enum Category
{
    None,
    Large,
    Small,
    Middle
}           

保障生産安全,再多一點努力也是值的。不放過每個小細節,讓你的服務在成長。