闽公网安备 35020302035485号
同时Options模式也提供了一种数据验证的机制。
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
接着在项目文件夹下创建PositionOptions类:


builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
有了上面的配置我们可以使用下面代码读取该配置:using AspNetCore.OptionsPattern.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace AspNetCore.OptionsPattern.Controllers
{
public class IOptionsInterfaceController : Controller
{
private IOptions<PositionOptions> _positionOptions;
public IOptionsInterfaceController(IOptions<PositionOptions> options)
{
_positionOptions = options;
}
public IActionResult Index()
{
return View(_positionOptions.Value);
}
}
}
2.2 IOptionsSnapshot<TOptions>接口using AspNetCore.OptionsPattern.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace AspNetCore.OptionsPattern.Controllers
{
public class IOptionsSnapshotInterfaceController : Controller
{
private IOptionsSnapshot<PositionOptions> _optionsSnapshot;
public IOptionsSnapshotInterfaceController(IOptionsSnapshot<PositionOptions> optionsSnapshot)
{
_optionsSnapshot = optionsSnapshot;
}
public IActionResult Index()
{
return View(_optionsSnapshot.Value);
}
}
}
2.3 IOptionsMonitor<TOptions>接口using AspNetCore.OptionsPattern.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
namespace AspNetCore.OptionsPattern.Controllers
{
public class IOptionsMonitorInterfaceController : Controller
{
private IOptionsMonitor<PositionOptions> _positionOptions;
public IOptionsMonitorInterfaceController(IOptionsMonitor<PositionOptions> optionsMonitor)
{
_positionOptions = optionsMonitor;
}
public IActionResult Index()
{
return View(_positionOptions.CurrentValue);
}
}
}
三. Options数据验证 "MyConfig": {
"Key1": "My Key One",
"Key2": 10,
"Key3": 32
}
我们在定义一个类来绑定上面节点:namespace AspNetCore.OptionsPattern.Models
{
public class MyConfigOptions
{
public const string MyConfig = "MyConfig";
// 堆代码 duidaima.com
[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$")]
public string Key1 { get; set; }
[Range(0, 1000, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
public int Key2 { get; set; }
public int Key3 { get; set; }
}
}
在启动类中添加如下代码:builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations();
调用AddOptions方法来获取一个OptionsBuilder<TOptions>对象,绑定到MyConfigOptions类,ValidateDataAnnotations方法来启用DataAnnotations的验证builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig))
.ValidateDataAnnotations()
.Validate(config =>
{
if (config.Key2 != 0)
{
return config.Key3 > config.Key2;
}
return true;
}, "Key3 must be > than Key2.");
我们也可以将验证逻辑放到单独的类中来实现。我们也可以自定义一个类来实现IValidateOptions<TOptions>实现我们的验证逻辑,接下来我们自定义一个验证逻辑类:using Microsoft.Extensions.Options;
using System.Text.RegularExpressions;
namespace AspNetCore.OptionsPattern.Models
{
public class MyConfigValidation : IValidateOptions<MyConfigOptions>
{
public MyConfigOptions _config { get; private set; }
public MyConfigValidation(IConfiguration config)
{
_config = config.GetSection(MyConfigOptions.MyConfig)
.Get<MyConfigOptions>();
}
public ValidateOptionsResult Validate(string name, MyConfigOptions options)
{
string? vor = null;
var rx = new Regex(@"^[a-zA-Z''-'\s]{1,40}$");
var match = rx.Match(options.Key1!);
if (string.IsNullOrEmpty(match.Value))
{
vor = $"{options.Key1} doesn't match RegEx \n";
}
if (options.Key2 < 0 || options.Key2 > 1000)
{
vor = $"{options.Key2} doesn't match Range 0 - 1000 \n";
}
if (_config.Key2 != default)
{
if (_config.Key3 <= _config.Key2)
{
vor += "Key3 must be > than Key2.";
}
}
if (vor != null)
{
return ValidateOptionsResult.Fail(vor);
}
return ValidateOptionsResult.Success;
}
}
}
修改启动类中的配置:builder.Services.AddOptions<MyConfigOptions>()
.Bind(builder.Configuration.GetSection(MyConfigOptions.MyConfig));
builder.Services.AddSingleton<IValidateOptions
<MyConfigOptions>, MyConfigValidation>();