environment.getenvironmentvariable 读不到 .env 文件变量,因其仅为普通文本文件,非系统环境变量;需用 dotnetenv 等库解析并注入,或手动读取后调用 environment.setenvironmentvariable。

为什么 Environment.GetEnvironmentVariable 读不到 .env 文件里的变量?
因为 .env 文件不是操作系统环境变量,它只是项目里一个普通文本文件。C# 的 Environment.GetEnvironmentVariable 只能读取系统或进程级已加载的环境变量,不会自动解析项目根目录下的 .env 文件。
你需要手动读取、解析并注入到当前进程环境变量中(可选),或者直接用字典管理配置值。
- 不注入进程环境变量:更安全,避免污染全局状态,推荐用于大多数应用
- 调用
Environment.SetEnvironmentVariable注入:后续调用Environment.GetEnvironmentVariable才能生效,但要注意作用域(EnvironmentVariableTarget.Process是默认且最常用) -
.env文件需 UTF-8 编码(无 BOM),否则中文可能乱码
用 DotNetEnv 库最省事:支持注释、引号、多行值
DotNetEnv 是目前 C# 生态中最接近 Node.js dotenv 行为的库,能正确处理带空格、等号、引号的值,也跳过以 # 开头的注释行。
安装方式:
dotnet add package DotNetEnv
基础用法(推荐在 Program.cs 或启动入口处执行):
DotNetEnv.Env.Load(); // 默认加载项目根目录下的 .env
如果 .env 在其他位置(如 config/.env):
DotNetEnv.Env.Load("config/.env");- 它会自动将每行
KEY=VALUE解析为环境变量,并调用Environment.SetEnvironmentVariable - 重复 key 会覆盖前一个;空行和
#开头的行被忽略 - 不支持变量插值(如
BASE_URL=https://api.example.com+API_URL=$BASE_URL/v1)
自己手写解析器:只依赖 System.IO,适合轻量或受控场景
如果你不想引入第三方包,且 .env 格式简单(无引号、无空格、无注释),可以用几行代码搞定:
var envPath = Path.Combine(AppContext.BaseDirectory, ".env");
if (File.Exists(envPath))
{
foreach (var line in File.ReadAllLines(envPath))
{
var trimmed = line.Trim();
if (string.IsNullOrEmpty(trimmed) || trimmed.StartsWith("#")) continue;
if (trimmed.Contains('='))
{
var parts = trimmed.Split(new char[] { '=' }, 2);
var key = parts[0].Trim();
var value = parts[1].Trim().Trim('"', '\'');
Environment.SetEnvironmentVariable(key, value, EnvironmentVariableTarget.Process);
}
}
}- 注意用
Split(..., 2)防止值中含等号被错误切分 -
Trim('"', '\'')去掉单/双引号包裹的值(常见于含空格的路径或 URL) - 没做转义处理(如
\n、\t),也不处理反斜杠续行 —— 这些属于高级需求,建议交给DotNetEnv
ASP.NET Core 中怎么集成?别直接改 Environment
在 ASP.NET Core 项目里,更推荐用内置的 IConfiguration 加载 .env,而不是往 Environment 里塞变量。这样配置可被 DI 自动注入,也兼容 appsettings.json 分层结构。
示例(Program.cs):
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddEnvironmentVariables(); // 先加系统变量
// 再加 .env(需先解析成 IDictionary<string, string>)
var envVars = DotNetEnv.Env.Parse(File.ReadAllText(".env"));
builder.Configuration.AddInMemoryCollection(envVars);- 这样
IConfiguration["DB_HOST"]就能取到.env里的值 - 优先级由添加顺序决定:后添加的配置源会覆盖前面同名 key
- 不要在
AddEnvironmentVariables()之后再调用DotNetEnv.Env.Load(),否则可能造成冗余注入
真正麻烦的不是读取,而是确保 .env 不被提交到 Git、不同环境用不同文件(如 .env.development)、以及敏感值不硬编码 —— 这些得靠 CI/CD 流程和团队约定来兜底。










