4

Just started messing with ASP.NET Core, pretty impressive so far. In the code generated,(see below). I want to change the hardcoded connection string to get it from the appsettings.json file.

This is apparently impossible. I haven't found a single example that works (or even builds).

What's going on?? Please help

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
            optionsBuilder.UseSqlServer("Server=xxxxxxx;Database=xxxxx;Trusted_Connection=True;");
        }
    }

The link provided solves the problem in one area but doesn't work here in OnConfiguring. What am I doing wrong ?

public class Startup
{
    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.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        var connection = Configuration.GetConnectionString("ConnectionName");
        services.AddDbContext<SurveyContext>(options => options.UseSqlServer(connection));
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

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

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}
djack109
  • 1,261
  • 1
  • 23
  • 42

3 Answers3

2

In the startup class of a .NET Core project you usually register this in the ConfigureServices function.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<YourContext>(options => options.UseSqlServer(connection));
}

When you are in the startup class of a .NET Core it is no problem to read the values from appsettings.json.

You could read more at Microsoft, i.e. here: https://learn.microsoft.com/en-us/ef/core/get-started/aspnetcore/existing-db

1

In the place where you want to access the appsettings.json,

JToken jAppSettings = JToken.Parse( 
      File.ReadAllText(Path.Combine(Environment.CurrentDirectory, 
      "appsettings.json")));

Now since you have the object, you can access its contents. Let me know if it works.

Minu
  • 232
  • 4
  • 13
  • if this is what he is trying to do, i would recommend using IConfiguration instead. it is already a json phrased string https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1 – Neville Nazerane Oct 30 '18 at 20:06
  • @NevilleNazerane nope, that doesn't help either – djack109 Oct 30 '18 at 20:10
  • @Minu this is the closest I found so far, at least in brongs the contents back. I just need a robust way of getting the contents out :) – djack109 Oct 30 '18 at 20:11
  • `IConfiguration` is the best way to access the information. it is clean and easy. but you need to understand how dependency injections work first https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1 – Neville Nazerane Oct 30 '18 at 20:17
  • this works`string conn = jAppSettings.SelectToken("ConnectionStrings").SelectToken("ConnectionName").Value();` – djack109 Oct 30 '18 at 20:17
  • 1
    the tricky thing about .net core is you need to understand an array of concepts before using it well – Neville Nazerane Oct 30 '18 at 20:18
  • @NevilleNazerane I get that. What I don't get is everything was working in say Asp.Net framework, why make things 10x harder – djack109 Oct 30 '18 at 20:21
  • Please do mark as answer if you think it helped you achieve the results @djack109 – Minu Oct 30 '18 at 20:21
  • the first time i set up `Scaffold-DbContext` it took me hours before i understood the setup. but once i did things are much cleaner and easier than .net framework – Neville Nazerane Oct 30 '18 at 20:24
  • 1
    This answer might have "worked", but I dont think its the right solution. Like @NevilleNazerane said, you need to use `IConfiguration`. You will have to make sure its generated correctly and u use the right path to your connection string. – Gerald Chifanzwa Oct 31 '18 at 09:40
1

When you use the Scaffold-DbContext, by default it hard codes your string into the DbContext class (so it works out of the box). You will need to register your DbContext in your startup class to proceed. To set this up, you can check the instructions in this answer.

Note that the Configuration property directly connects to your appsettings.json and several other locations. You can read more about it in this documentation. While you can always use the appsettings.json file, it is generally recommended to have your secure secrets in an external json file outside your source code. The best solution for this during development is using the secret manager. The easiest way to use this is right click on your project on visual studio and select "manage user secrets". This will open a json file that is already connected to your Configuration object.

Once this is set up, you need to use dependency injection to access your db context.

public class HomeController : Controller
{


     public HomeController(SurveyContext context)
     {
         // you can set the context you get here as a property or field
         // you can use visual studio's shortcut ctrl + . when the cursor is on "context"

         // you can then use the context variable inside your actions
     }
}

When you use using, it creates a new connection each time. Using injection makes sure only one connection is created per request no matter how many times it is used.

Neville Nazerane
  • 6,622
  • 3
  • 46
  • 79