Rich G
Rich G

Reputation: 103

ASP.NET MVC Failing to Access appsettings.JSON

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

Answers (3)

Mauricio Gracia Gutierrez
Mauricio Gracia Gutierrez

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

Rich G
Rich G

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

Vishal Bakshi
Vishal Bakshi

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

Related Questions