Brnsn
Brnsn

Reputation: 33

Error finding connection string in Blazor .net core app

I have a .netcore 3.1 blazor app with EF Core 5 and after scaffolding my database with Scaffold-DbContext "Name=MyDb" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force

Everything works without issue if I use Scaffold-DbContext "Server=servername;Database=MyDb;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force But I want to avoid having the connection string in the source code.

everything scaffolds correctly, however, when I try to display data to a list, a get this error: System.InvalidOperationException: A named connection string was used, but the name 'MyDb' was not found in the application's configuration. Note that named connection strings are only supported when using 'IConfiguration' and a service provider, such as in a typical ASP.NET Core application. See https://go.microsoft.com/fwlink/?linkid=850912 for more information.

Below is the code for my appsettings.json:

{
"ConnectionStrings": {
    "MyDb": "Server=servername;Database=MyDb;Integrated Security=True"
  }
}

Here is my MyDb_Context:

    public partial class MyDb_Context : DbContext
    {
        public MyDb_Context()
        {
        }

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

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseSqlServer("Name=MyDb");
            }
        }
...
}

Here is my Startup.cs:

    public class Startup
    {
        public Startup(IConfiguration configuration, IWebHostEnvironment env)
        {
            Configuration = configuration;
            _env = env;
        }

        private readonly IWebHostEnvironment _env;
        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            var connection = Configuration.GetConnectionString("MyDb");
            services.AddDbContext<MyDb_Context>(options => options.UseSqlServer(connection));
        }
...
}

And here is what is being called in my service:

 public class MyDbService
    {
        public readonly MyDb_Context mydb_context;

        public MyDbService(MyDb_Context mydbctx)
        {
            MyDb_Context = mydbctx;
            MyDb_Context.Database.SetCommandTimeout(60);
        }

        public Task<List<MyDbTableName>> GetMyDbContent()
        {
            var usernames = mydb_context.usernames.Where(u => u.AppId == 2).ToListAsync();

            return usernames ;
        }
...
}

Then in my Razor page I am using the following code:

@code{
       private List<usernames> _usernames;

       
       MyDbService mydbservice = new MyDbService(new MyDb_Context()); //I think this line is where it is breaking

       protected override async Task OnInitializedAsync()
        {
            //Grab function from the service listed above
            //Function:
            _usernames = await mydbservice.GetMyDbContent();
        }

}

I have no idea why its not finding the connectionstring, and I can even put a breakpoint on startup.cs on optionsBuilder.UseSqlServer("Name=MyDb"); and it is able to read the connection string perfectly fine.

I also can see that DBContext gets loaded in when try services.toList(); and breakpoint on it.

Please help, I have been at this for over a week and have exhausted my efforts.

Upvotes: 2

Views: 2837

Answers (3)

M.Hassan
M.Hassan

Reputation: 11032

  • Register the service MyDbService in the Startup class to be injected latter by DI:
public void ConfigureServices(IServiceCollection services)
        {
            //...other services            
            services.AddScoped<MyDbService>();
        }
  • Inject the service into the component
@* inject the service *@
@inject MyDbService mydbservice
 
//....

@code{
    private List<usernames> _usernames;

//DO NOT instianate the service, it's injected 
   // MyDbService mydbservice = new MyDbService(new MyDb_Context()); //I think this line is where it is breaking

    protected override async Task OnInitializedAsync()
    {
        //Grab function from the service listed above
        //Function:
        _usernames = await mydbservice.GetMyDbContent(); //now it's working
    }
}

  • Modify the next line in the Constructor of MyDbService:
  // MyDb_Context = mydbctx; //invalid
  mydb_context = mydbctx;

The Scaffold-DbContext using named connection is valid because we are using DI.

Scaffold-DbContext "Name=MyDb" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force

I tested this solution and it's working fine.

Upvotes: 2

Nb777
Nb777

Reputation: 2032

In your MyDb_Context page, I didn't see puplic dbset<MyModel> Object {get; set;} , you need it to query and save an instance of your model!

Upvotes: 0

mj1313
mj1313

Reputation: 8459

I doubt the Scaffold-DbContext Command has problem. I think you should give the complete connection string, something like this:

Scaffold-DbContext "Server=servername;Database=MyDb;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDb_Context -Force

Upvotes: 0

Related Questions