Reputation: 103
I have an issue that I cannot access the settings within my appsettings.json file.
I have set the class as this :
public class apisettings
{
public const string SectionName = "LocalConfig";
public string Url { get; set; }
}
The section in the appsettings.json is as follows :
"LocalConfig": {
"Url": "https://someurl.com/api/"
}
In my Startup.cs I have the following (please excuse all the additional parts for Azure Authentication) :
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
services.AddRazorPages()
.AddMicrosoftIdentityUI();
services.AddOptions();
services.Configure<apisettings>(Configuration.GetSection(apisettings.SectionName));
}
In my controller I have it set as per the following :
public static string URL = "";
public IActionResult Index(IOptions<apisettings> apisettings)
{
URL = apisettings.Value.Url;
return View();
}
Now every time I access that particular section of the application I get an error that states "Could not create an instance of type 'Microsoft.Extensions.Options.IOptions`1[[ManagementApplication.Models.apisettings, ManagementApplication, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'. Model bound complex types must not be abstract or value types and must have a parameterless constructor. Record types must have a single primary constructor. Alternatively, give the 'apisettings' parameter a non-null default value."
I am sure I am missing something very simple, but please help?
UPDATE
I have edited the class as per the advice below so it now shows as :
public class apisettings
{
public apisettings()
{
}
public const string SectionName = "LocalConfig";
public string Url { get; set; }
}
It is still giving me exactly the same error, I know I am missing something simple but can't find it :(
Upvotes: 1
Views: 368
Reputation: 10864
Model bound complex types must not be abstract or value types and must have a parameterless constructor
Add a constructor method without parameters
public class apisettings
{
public apisettings() {
}
public const string SectionName = "LocalConfig";
public string Url { get; set; }
}
Since you are still getting the same error, I think you should check that you are following this pattern https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-5.0
Upvotes: 1
Reputation: 103
After much trawling through the answers and the internet I was missing a very simple piece of the puzzle. The IOptions was being created in the services and I needed to refer to that in the Controller code to make sure it knew where to look.
The below is a cut down version of all the code with only the relevant parts included so anyone can follow the solution.
I have set the class as this :
public class apisettings
{
public apisettings() { }
public apisettings(string url)
{ Url = url; }
public string Url { get; set; }
}
The section in the appsettings.json is as follows :
"LocalConfig": {
"Url": "https://someurl.com/api/"
}
In my Startup.cs I have the following :
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
services.AddOptions();
services.Configure<apisettings> Configuration.GetSection("LocalConfig"));
}
In my controller I have it set as per the following :
public static string URL = "";
public IActionResult Index([FromServices] IOptions<apisettings> apisettings)
{
URL = apisettings.Value.Url;
return View();
}
The key to the solution was adding the [FromServices] to the declaration.
Upvotes: 1
Reputation: 121
Looks like the apisettings class has got some other constructor configured and you are trying to call the default constructor. A very good explanation has been provided here
Add a default constructor as below
public apisettings() { };
Upvotes: 1