I have a simple controller that reads some configuration from appsettings.json
using the Options pattern. It works fine as long as appsettings.json
is configured correctly. However, what if my configuration section is missing from appsettings.json
? I hoped to get an Exception
or null
, but instead I get a MySettings
object with default values (i.e. MyProperty
is null
).
MyController.cs
public class MyController : Controller
{
private readonly string value;
public MyController(IOptions<MySettings> options)
{
// Can I validate the `options` object here?
this.value = options.Value.MyProperty;
}
[HttpGet("api/data")]
public ActionResult<string> GetValue()
{
return this.Ok(this.value);
}
}
MySettings.cs
public class MySettings
{
public string MyProperty { get; set; }
}
Startup.cs (only showing relevant code)
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Tried this:
services.Configure<MySettings>(Configuration.GetSection("MySettings"));
// Tried this too:
services.Configure<MySettings>(options => Configuration.GetSection("MySettings").Bind(options));
}
}
appsettings.json
{
"MySettings": {
"MyProperty": "hello world"
}
}
2
Answers
I found one possible solution on this SO answer.
Add an extensions method to validate:
Use that extension method to validate & register the instance in Startup.cs:
Change the controller constructor to accept the
MySettings
object directly (instead ofIOptions<MySettings>
):Another nice consequence of this approach is it removes our dependency on
IOptions
which simplifies the controller a bit.You can enforce it in the following way:
ValidateDataAnnotations
afterBind
callOptionsValidationException