1

I have a problem to my .net core application. This problem is user secret json file can not read. Application work fine on development but application gives me error on release version in hosting server.

Error code some bellow

Application startup exception: System.ArgumentNullException: Value cannot be null. Parameter name: Password at System.Data.SqlClient.SqlConnectionStringBuilder.set_Password(String value) at myApplicationCore.WebUI.Startup.ConfigureServices(IServiceCollection services) in C:\Users\myComp\source\repos\myApplicationCore\myApplicationCore.WebUI\Startup.cs:line 42 --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services) at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices() at Microsoft.AspNetCore.Hosting.Internal.WebHost.Initialize() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication() crit: Microsoft.AspNetCore.Hosting.Internal.WebHost[6] Application startup exception System.ArgumentNullException: Value cannot be null. Parameter name: Password at System.Data.SqlClient.SqlConnectionStringBuilder.set_Password(String value) at myApplicationCore.WebUI.Startup.ConfigureServices(IServiceCollection services) in C:\Users\myComp\source\repos\myApplicationCore\myApplicationCore.WebUI\Startup.cs:line 42 --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services) at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices() at Microsoft.AspNetCore.Hosting.Internal.WebHost.Initialize() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication() Hosting environment: Production Content root path: D:\vhosts\mydomainexample.com\httpdocs Now listening on: http://127.0.0.1:25696 Application started. Press Ctrl+C to shut down. Application is shutting down...

My Startup.cs file

public class Startup
{

    public IConfiguration Configuration;

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        var builder = new SqlConnectionStringBuilder(Configuration.GetConnectionString("DefaultConnection"));
        builder.Password = Configuration["DbPassword"];

        services.AddDbContext<ApplicationDbContext>(options => options.UseMySql(builder.ConnectionString,
            b =>
            {
                b.MigrationsAssembly("myApplicationCore.WebUI");
                b.ServerVersion(new Version(5, 6, 44), ServerType.MySql); // replace with your Server Version and Type
            }
            ));

        services.AddIdentity<ApplicationUser, IdentityRole>(opts => {
            opts.User.RequireUniqueEmail = true;
            opts.Password.RequiredLength = 3;
            opts.Password.RequireNonAlphanumeric = false;
            opts.Password.RequireLowercase = false;
            opts.Password.RequireUppercase = false;
        })
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

        services.AddTransient<IUnitOfWork, EfUnitOfWork>();
        services.AddTransient<IEmailSender, EmailSender>();
        services.Configure<AuthMessageSenderOptions>(Configuration);

        services.ConfigureApplicationCookie(options => options.LoginPath = "/Account/Sign");

        services.AddMvc().AddJsonOptions(options =>
        {
            options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        services.AddSignalR();
    }

    // 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.UseStatusCodePages();
        app.UseStaticFiles();
        app.UseAuthentication();

        app.UseSignalR(routes =>
        {
            routes.MapHub<HubSignal>("/hubCon");
        });

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

            routes.MapSpaFallbackRoute(
            name: "spa-fallback",
            templatePrefix: "Portal",
            defaults: new { controller = "Portal", action = "Index" });
        });

        SeedData.EnsurePopulated(app);
        SeedData.CreateRoles(app.ApplicationServices).Wait();
        SeedData.CreateIdentityUsers(app.ApplicationServices).Wait();

    }
}

This is my Program.cs file

    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();

It gives me this error when I enter in to the web address.

An error occurred while starting the application. .NET Core 4.6.27817.03 X86 v4.0.0.0 | Microsoft.AspNetCore.Hosting version 2.2.0-rtm-35687 | Microsoft Windows 10.0.14393 | Need help?

I think server can not find secret.json file but I don't know how can I find file.

How can i solve this problem ?

Thanks for helping.

Avoraa
  • 95
  • 1
  • 2
  • 8
  • Where do you *configure* the application? `Configuration["DbPassword"]` will return the password only if that setting gets loaded from the configuration, wherever that is - file, database, key vault etc. – Panagiotis Kanavos Sep 09 '19 at 13:21
  • `gives me error on release version in hosting server.` did you copy the correct configuration files to the production server? You didn't post any configuration code so one can only guess what you mean by `user secret json file` – Panagiotis Kanavos Sep 09 '19 at 13:23
  • @PanagiotisKanavos There is no secret.json file on the server. But why does the error line say the extension of the computer that I developed the application for ? C:\Users\myComp\source\repos\myApplicationCore\myApplicationCore.WebUI\Startup.cs:line 42 - this line my computer but application on server now – Avoraa Sep 09 '19 at 13:27
  • Because that's where the error occured. There's no source code on the server. When an error occurs the .NET runtime checks for any matching debug files to match the error location to the source code – Panagiotis Kanavos Sep 09 '19 at 13:33
  • @PanagiotisKanavos I updated my post, I added my program.cs so i have no use any configuration – Avoraa Sep 09 '19 at 13:35
  • I suspect you should [check the documentation](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.2) and tutorials - you *do* have configuration files. [CreateDefaultBuilder adds the appsetings.**.json](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.2#environment-variables-configuration-provider) files by default. – Panagiotis Kanavos Sep 09 '19 at 13:38
  • @PanagiotisKanavos How can i solve this problem ? how can i access user secrets on server hosting ? Can i programitically create this file ? – Avoraa Sep 09 '19 at 13:39
  • No, read the documentation *first*. You have to *copy* or *create* those files on the server. Where do you store those `user secrets`? In `appsettings.json`? In `appsettings.Development.json` or `appsettings.Production.json`? You have to copy the correct file to the server – Panagiotis Kanavos Sep 09 '19 at 13:40
  • @PanagiotisKanavos I reviewed the documents, but I couldn't. I think I should give up, I will transfer the database information to "appsettings.json". – Avoraa Sep 09 '19 at 14:00
  • No, put them in `appsettings.Production.json`. – Panagiotis Kanavos Sep 09 '19 at 14:19

1 Answers1

1

User secrets is not supported outside of Visual Studio. It's specifically and exclusively for development.

Despite the name, it's not actually secret anyways. It's still just plain old JSON and everything is stored plain-text, unencrypted. The only benefit to it is that it gives you place to store configuration in development outside of the project, so it doesn't accidentally end up in source control. That's it. As a production config option, it would be worse than useless.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Then why does microsoft recommend the use of "user secrets"? – Avoraa Sep 09 '19 at 14:10
  • See my updated answer. It keeps secrets out of source control. That's it. For production, you need another strategy. – Chris Pratt Sep 09 '19 at 14:11
  • I transfer the database information into the appsettings.json file again. – Avoraa Sep 09 '19 at 14:19
  • @Avoraa no, put it in `appsettings.*Production*.json`. The values in that file override the settings in appsettings.json. – Panagiotis Kanavos Sep 09 '19 at 14:19
  • @PanagiotisKanavos What different ? There are two files, one is "appsettings.json" and the other is "appsettings.development.json" this file does not exist "appsettings.production.json" – Avoraa Sep 09 '19 at 14:27
  • @PanagiotisKanavos, most likely `appsettings.Production.json` ends up in source control as well. I recommend using environment variables, these also overwrite appsettings.json as well. different hosting environments provide different ways of passing env variables, e.g. in docker u `docker run -e DbPassword=blablabla imagename`. – Gerald Chifanzwa Sep 09 '19 at 14:30
  • @gerryc.inc better than storing the production credentials in `appsettings.json`. If there's no better mechanism, user secrets in production would be just fine. And no, environment variables aren't *safer* - someone has to set them and *every* application on that machine can read them. That lead to a *lot* of hacks back in the CGI days. Docker alleviates this because there are not "other" applications in the container – Panagiotis Kanavos Sep 09 '19 at 14:32
  • The only truly secure built in config provider is Azure Key Vault, which can actually encrypt secrets at rest. Anything else is stored plain text. However, environment variables are usually considered "secure enough". While they're stored plain-text, it would require server-level access to read them, and if there's something malicious with server-level access, then you've got more problems than exposing database credentials. Absolutely do *not* use JSON, though. – Chris Pratt Sep 09 '19 at 15:43