【问题标题】:System.ArgumentNullException: Value cannot be null. (Parameter 'connectionString') asp.net Core Docker-composeSystem.ArgumentNullException:值不能为空。 (参数'connectionString') asp.net Core Docker-compose
【发布时间】:2020-05-16 08:08:27
【问题描述】:

我有一个 dockerized asp.net Core 应用程序试图连接到一个 mySql 数据库。两者都在 docker-compose 中运行。当我在没有 Docker 的情况下测试与本地数据库的连接时,我的代码工作正常,但是当我将它部署在 docker-compose 内的 Vm 上并调用我的控制器之一时,我收到此错误:System.ArgumentNullException : 值不能为空。 (参数'connectionString')。 这是我的 docker-compose :

version: '3'
services:
  dbgil:
   container_name: dbgil
   image: mysql
   restart: always
   ports:
     - 3306:3306
   environment:
     MYSQL_ROOT_PASSWORD: root
   volumes:
     - dbdata:/var/lib/mysql
  webserver:
    depends_on:
      - dbgil
    image: lionelquirynen/gillesquirynensys:latest
    ports:
      - "8021:80"
    links:
      - dbgil
volumes:
    dbdata:

这是我在我的 asp.net 核心应用程序中的启动:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using GillesQuirynenSys.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace GillesQuirynenSys
{
    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.AddControllers();
            services.AddDbContext<MySqlDbContext>(options =>
                options.UseMySql("server=localhost;port=3306;database=test;user=root;password=root;convert zero datetime=True"));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MySqlDbContext context)
        {
            context.Database.EnsureCreated();
            var databaseCreator = context.GetService<IRelationalDatabaseCreator>();
            databaseCreator.CreateTables();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}


我首先在我的 appsettings.json 中有我的连接字符串,但我遇到了同样的错误,所以我尝试对其进行硬编码,但它没有改变任何东西。有人有什么想法吗?看来我的配置工作正常(至少,它在本地没有 Docker)。

PS:这是我的 asp.net Core 应用程序在将其推送到 DockerHub 之前的 DockerFile:

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["GillesQuirynenSys/GillesQuirynenSys.csproj", "GillesQuirynenSys/"]
RUN dotnet restore "GillesQuirynenSys/GillesQuirynenSys.csproj"
COPY . .
WORKDIR "/src/GillesQuirynenSys"
RUN dotnet build "GillesQuirynenSys.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "GillesQuirynenSys.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "GillesQuirynenSys.dll"]

【问题讨论】:

  • 如果我没记错的话,您应该使用 mysql 服务的名称,所以在 docker 容器中运行的连接字符串中使用 dbgil 而不是 localhost。尝试替换这段代码:server=localhost;"server=dbgil;

标签: c# mysql docker asp.net-core docker-compose


【解决方案1】:

很高兴我的回答有所帮助。 所以基本上在docker容器中,MySQL db的服务器名和docker-compose.yml文件中声明的服务名是一样的。

对您的代码还有一点说明: 而不是这个:

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddDbContext<MySqlDbContext>(options =>
                options.UseMySql("server=localhost;port=3306;database=test;user=root;password=root;convert zero datetime=True"));
        }

-> 硬编码连接字符串的位置

试试这个:

      public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddDbContext<MySqlDbContext>(options =>
                options.UseMySql(Configuration.GetConnectionString("DefaultConnection")));
        }

并调整您的 appsettings.json 文件 - 对于生产(docker 容器)构建,您将拥有:

{
  "ConnectionStrings": {
    "DefaultConnection": "server=dbgil;port=3306;database=test;user=root;password=root;convert zero datetime=True"
  }
...
}

appsettings.Development.json 中,您将拥有Development 模式(您的本地主机)的连接字符串:

{
  "ConnectionStrings": {
    "DefaultConnection": "server=localhost;port=3306;database=test;user=root;password=root;convert zero datetime=True"
  }
...
}

【讨论】:

  • 我知道我知道,我对它进行了硬编码,因为我收到了 null 异常的错误,但现在我把它改回来了 :) 无论如何,谢谢,它现在可以正常工作了!
  • 当然,你能接受我的回答,因为它是正确的解决方案吗?:P
  • 我刚刚做了 ;) 祝你有美好的一天 :)
猜你喜欢
  • 2021-10-11
  • 1970-01-01
  • 2020-09-25
  • 2019-11-01
  • 2021-11-18
  • 1970-01-01
  • 2019-08-17
  • 2021-07-02
  • 2018-06-03
相关资源
最近更新 更多