4

Disclaimer:I am trying to learn more about net 6.0 and am a rookie.

Here is what i am trying to do:

  • I am trying to access IConfiguration file in a TransparencyContext but i keep on getting configuration being null error:System.ArgumentNullException: 'Value cannot be null. (Parameter 'connectionString')'.

Here is what I did:

  • updated the dbContext's constructor to inject IConfiguration config

Most of this Context file is automatically generated and the only thing i did was updated the public TransparencyContext(IConfiguration config) to include the Iconfig so i could access it in optionsBuilder.UseSqlServer(config.GetConnectionString("SQLDB"));

TransparencyContext.cs

  namespace EFTutorial.Models
{
    public partial class TransparencyContext : DbContext
{
    private readonly IConfiguration config;

    public TransparencyContext()
    {
    }
    public TransparencyContext(IConfiguration config)
    {
        this.config = config;
    }

    public TransparencyContext(DbContextOptions<TransparencyContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Fundraiser> Fundraisers { get; set; } = null!;
    public virtual DbSet<Person> Persons { get; set; } = null!;

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer(config.GetConnectionString("SQLDB"));
        }
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Fundraiser>(entity =>
        {
            entity.Property(e => e.Description).IsUnicode(false);

            entity.Property(e => e.EndDate).HasColumnType("datetime");

            entity.Property(e => e.Goal).HasColumnType("decimal(18, 2)");

            entity.Property(e => e.Name)
                .HasMaxLength(1000)
                .IsUnicode(false);
        });

        modelBuilder.Entity<Person>(entity =>
        {
            entity.Property(e => e.DateOfBirth).HasColumnType("datetime");

            entity.Property(e => e.FirstName)
                .HasMaxLength(100)
                .IsUnicode(false);

            entity.Property(e => e.LastName)
                .HasMaxLength(100)
                .IsUnicode(false);
        });

        OnModelCreatingPartial(modelBuilder);
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}

I try then to test it from home controller by doing this.

private TransparencyContext _transparencyContext;
        public HomeController(ILogger<HomeController> logger)
        {
            _logger = logger;
            _transparencyContext = new();
        }
public IActionResult Index()
        {
            var p = new Person();
            p.FirstName = "Entity";
            p.LastName = "Framework";

            _transparencyContext.Persons.Add(p);
            _transparencyContext.SaveChanges();
            return View();
        }

When i do this i get the config variable( in TransparencyContext) being null (System.ArgumentNullException: 'Value cannot be null(Parameter 'connectionString')'). I havent changed my program.cs and is the way it was when the project was created.

Program.cs

 var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

app.Run();

I know that configuration file can be accessed from app.Configuration but not sure how to make configuration accessible for the TransparencyContext.cs so i can get the connection string for db.I have tried looking at Microsoft documents but they don't show how they make the Iconfiguration avaiable and only show them using it.Any help is much appreciated.

I am thinking I might need to register a service to configuration but not sure how to do it.

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "SQLDB": "Server=AzureConnectionStringCopyPaste"
  }
}
9
  • Any particular reason for manually creating context in controller (i.e. _transparencyContext = new()) instead of registering and resolving via DI (as in the docs)? Commented Jan 7, 2022 at 23:12
  • What does your appsettings file look like? Do you have a connection string in there? Commented Jan 7, 2022 at 23:13
  • @DavidG I do have it there. Its just when debugging config variable is null on TransparencyContext.cs Commented Jan 7, 2022 at 23:16
  • Then show us what it looks like Commented Jan 7, 2022 at 23:16
  • @GuruStron No reason, Thank you for pointing this out. Will create a service for this but it doesnt solve the issue of config being null. Commented Jan 7, 2022 at 23:17

2 Answers 2

2

The quick fix to your current setup would be just injecting IConfiguration into the controller and using it to construct the context:

public HomeController(ILogger<HomeController> logger, IConfiguration cfg)
{
    _logger = logger;
    _transparencyContext = new(cfg);
}

But "correct" and idiomatic way is to use DI to register and resolve the context:

  1. remove all constructors except TransparencyContext(DbContextOptions<TransparencyContext> options)
  2. Register context in the DI with AddDbContext or AddDbContextFactory:
builder.Services.AddDbContextFactory<TransparencyContext>(opts =>
 opts.UseSqlServer(builder.Configuration.GetConnectionString("SQLDB")));
  1. Resolve in the controller
public HomeController(ILogger<HomeController> logger, TransparencyContext ctx)
{
    _logger = logger;
    _transparencyContext = ctx;
}
Sign up to request clarification or add additional context in comments.

Comments

1
  1. the default configuration file name is appsettings.json (not AppSettings.Json)

  2. You should configure your configuration in the host builder. Example:

     var configuration = new ConfigurationBuilder()
                                 .AddJsonFile("appsettings.json", false, true)
                                 .AddEnvironmentVariables()
                                 .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", true, true)
                                 .Build();
    
    builder.UseConfiguration(configuration)
    
  3. Also you can use WebBuilder method .ConfigureAppConfiguration to configure is using AppConfiguration

2 Comments

1. what does make you think it is named "AppSettings.Json"? 2. No, it is not required since appsettings.json is added by default.
I typed in stackoverflow wrong but spelling on my app was appsettings.json. Most of the stuff is default, i havent touched anything besides adding EF.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.