配置User Secrets

ABP踩坑记录-目录

起因

因为以往习惯在User Secrets中保存连接字符串之类信息,但当我把连接字符串移到secrets.json中后,却发现在迁移过程中会报如下的错误:

简单说,也就是迁移时无法获取到连接字符串信息。

解决方案

  1. Qincai.EntityFrameworkCore项目中,找到QincaiDbContextFactory.cs文件,修改如下注释处代码。

    public class QincaiDbContextFactory : IDesignTimeDbContextFactory<QincaiDbContext>
    {
    public QincaiDbContext CreateDbContext(string[] args)
    {
    var builder = new DbContextOptionsBuilder<QincaiDbContext>();
    //var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
    var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder(), addUserSecrets: true); QincaiDbContextConfigurer.Configure(builder, configuration.GetConnectionString(QincaiConsts.ConnectionStringName)); return new QincaiDbContext(builder.Options);
    }
    }

经历

这个问题看似解决容易,但还是费了我不少时间才找到原因。

首先,我怀疑是不是secrets.json文件有问题,就把Qincai.Web.Host.csproj中的UserSecretsId删掉,重新生成了一个。但难受的是,这下不单是迁移有问题了,连应用都无法启动了,当然报错信息也是无法找到连接字符串。

所以,我开始在StartUp中找注入配置的代码,然后发现不同于微软模板代码中直接注入IConfiguration对象的做法,Module Zero自己实现了一个拓展方法IHostingEnvironment.GetAppConfiguration。其源码如下:

public static IConfigurationRoot GetAppConfiguration(this IHostingEnvironment env)
{
// 这里第三个参数代表是否添加User Secrets
// 可以看到Module Zero默认只在开发环境中添加
return AppConfigurations.Get(env.ContentRootPath, env.EnvironmentName, env.IsDevelopment());
}

这里调用了AppConfigurations类,注意这个类是定义在Qincai.Core项目中,这是导致问题的关键。

然后,我们来研究一下AppConfigurations类中的这段代码:

private static IConfigurationRoot BuildConfiguration(string path, string environmentName = null, bool addUserSecrets = false)
{
var builder = new ConfigurationBuilder()
.SetBasePath(path)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); if (!environmentName.IsNullOrWhiteSpace())
{
builder = builder.AddJsonFile($"appsettings.{environmentName}.json", optional: true);
} builder = builder.AddEnvironmentVariables(); if (addUserSecrets)
{
// 在这里添加了User Secrets
builder.AddUserSecrets(typeof(AppConfigurations).GetAssembly());
} return builder.Build();
}

乍一看好像没问题,但是注意,我刚才说了AppConfigurations是属于Qincai.Core项目,即根据默认的配置,typeof(AppConfigurations).GetAssembly()获取到的是Qincai.Core.dll下的程序集。

也就是说,这里添加的User Secrets是根据Qincai.Core.csproj中定义的UserSecretsId,而不是Qincai.Web.Host.csproj中定义的。

打开Qincai.Core.csproj,我们确实注意到有一个UserSecretsId字段,且和Qincai.Web.Host.csproj中未修改器前的一致。

这里就是Module Zero取巧的地方了,因为在VS中,只有Web项目才能在右键中找到管理用户机密,所以通过两个配置两个相同的UserSecretsId,使其能通过VS的快捷方式修改Qincai.Core项目的secrets.json文件。

既然找到原因了,那么只需将UserSecretsId恢复成一致即可,痛快地敲下F5,启动成功。

因此注意,一旦在你修改了Qincai.Web.Host.csproj中的UserSecretsId后,千万不要忘了修改Qincai.Core.csproj,务必确保两个UserSecretsId一致,不然你再怎么改,程序也是届不到的。


不是完了吗?才怪嘞!!我们的问题是迁移时无法读取User Secrets,以上经历只能说又回到了起点。

到这里,我们已经可以在程序运行时成功读取到User Secrets,但是在数据库迁移过程中,还是会报错:

System.ArgumentNullException: Value cannot be null.
Parameter name: connectionString

让我们打开ef工具的详细输出-v来看一看,其中有这么一段输出:

Finding DbContext classes...
Finding IDesignTimeDbContextFactory implementations...
Finding application service provider...
Finding IWebHost accessor...
Using environment 'Development'.
Using application service provider from IWebHost accessor on 'Program'.
Finding DbContext classes in the project...
Found DbContext 'QincaiDbContext'.
Using DbContext factory 'QincaiDbContextFactory'.

它提到了QincaiDbContextFactory这个类,源码如下:

/* This class is needed to run "dotnet ef ..." commands from command line on development. Not used anywhere else */
public class QincaiDbContextFactory : IDesignTimeDbContextFactory<QincaiDbContext>
{
public QincaiDbContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<QincaiDbContext>();
// 注意这里
var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder(); QincaiDbContextConfigurer.Configure(builder, configuration.GetConnectionString(QincaiConsts.ConnectionStringName)); return new QincaiDbContext(builder.Options);
}
}

看到注释,我们应该就是找对地方了,注意我在代码中标出的位置。它也通过AppConfigurations.Get来获取配置,但是没有给出AddUserSecrets参数(默认为false),而根据此前的代码可知,它没有添加User Secrets。

那么解决方案就很简单了,显式给出AddUserSecrets参数即可。

var configuration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder(), addUserSecrets: true);

ABP框架入门踩坑-配置User Secrets的更多相关文章

  1. ABP框架入门踩坑-配置数据库表前缀

    配置数据库表前缀 ABP踩坑记录-目录 本篇其实和ABP关系并不大,主要是EF Core的一些应用-.-. 起因 支持数据库表前缀应该是很多应用中比较常见的功能,而在ABP中并没直接提供这一功能,所以 ...

  2. ABP框架入门踩坑-添加实体

    添加实体 ABP踩坑记录-目录 这里我以问答模块为例,记录一下我在创建实体类过程中碰到的一些坑. 审计属性 具体什么是审计属性我这里就不再介绍了,大家可以参考官方文档. 这里我是通过继承定义好的基类来 ...

  3. ABP框架入门踩坑-使用MySQL

    使用MySQL ABP踩坑记录-目录 起因 因为我自用的服务器只是腾讯云1核1G的学生机,不方便装SQL Server,所以转而MySQL. 这里使用的MySQL版本号为 8.0. 解决方案 删除Qi ...

  4. 我的微信小程序入门踩坑之旅

    前言 更好的阅读体验请:我的微信小程序入门踩坑之旅 小程序出来也有一段日子了,刚出来时也留意了一下.不过赶上生病,加上公司里也有别的事,主要是自己犯懒,就一直没做.这星期一,赶紧趁着这股热乎劲,也不是 ...

  5. 【ABP框架系列学习】启动配置(5)

    ABP提供了在启动时配置模块的基础设施和模型. 1.配置ABP 配置ABP是在模块的PreInitialize方法中完成的,例如: public class SimpleTaskSystemModul ...

  6. Go ORM框架 - GORM 踩坑指南

    今天聊聊目前业界使用比较多的 ORM 框架:GORM.GORM 相关的文档原作者已经写得非常的详细,具体可以看这里,这一篇主要做一些 GORM 使用过程中关键功能的介绍,GORM 约定的一些配置信息说 ...

  7. 基于ASP.NET MVC的ABP框架入门学习教程

    为什么使用ABP 我们近几年陆续开发了一些Web应用和桌面应用,需求或简单或复杂,实现或优雅或丑陋.一个基本的事实是:我们只是积累了一些经验或提高了对,NET的熟悉程度. 随着软件开发经验的不断增加, ...

  8. 小程序框架MpVue踩坑日记(一)

    小程序也做了几个小功能模块了,总觉得需要总结一下,踩坑什么的还是得记录一下啊. 好吧,其实是为了方便回顾 首先,说到小程序框架,大家都知道wepy,不过,我是没用过 美团开发团队到mpvue到是个实在 ...

  9. ABP框架入门

    技术要求 在开始使用 ABP 框架之前,您需要在计算机上安装一些工具. IDE/编辑器 本书假设您使用的是Visual Studio 2022(支持 .NET 6.0 的 v10.0)或更高版本.如果 ...

随机推荐

  1. OOP的几个不常用的方法

    from OOP_多态 import cat c = cat("cat") print(c.__doc__) print(cat.__doc__) # # 打印类的描述信息,也就是 ...

  2. Parallel.Foreach的基础知识

    微软的并行运算平台(Microsoft’s Parallel Computing Platform (PCP))提供了这样一个工具,让软件开发人员可以有效的使用多核提供的性能. Visual Stud ...

  3. phpstorm2018.3的安装和激活和汉化

    安装 第一步:解压并打开文件,运行安装程序,点击Next进入下一步, 第二步:选择软件安装目录,自定义选择安装根目录--> 注意!后面还需要找安装目录里的文件,所以记住安装到一个比较容易查看的目 ...

  4. CentOS7下部署NTP Server

    系统环境:CentOS Linux release 7.4.1708 (Core) 3.10.0-693.el7.x86_64 软件版本:chrony-3.1-2.el7.centos.x86_64 ...

  5. Linux Doxygen的安装和使用

    一.简介 Doxygen是一种开源跨平台的,以类似JavaDoc风格描述的文档系统,完全支持C.C++.Java.Objective-C和IDL语言,部分支持PHP.C#.注释的语法与Qt-Doc.K ...

  6. github 如何添加项目代码

    1.点添加一个resporitory 2.添加的时候一定要选上下面的添加readme这个选项 3.点进去点code就能create file了.贴上代码就行.主要是第二步必须选对

  7. 学习bn算法

    好处: 1.归一化后有什么好处呢?原因在于神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低: 2.另外一方面,一旦每批训练数据的分布各不相同(b ...

  8. vertical-align和text-align

    vertical-align只适用于内联元素. 垂直对齐:vertical-align属性(转) 行高与单行纯文字的垂直居中,而如果行内含有图片和文字,在浏览器内浏览时,读者可以发现文字和图片在垂直方 ...

  9. 2018.10.23 bzoj1297: [SCOI2009]迷路(矩阵快速幂优化dp)

    传送门 矩阵快速幂优化dp简单题. 考虑状态转移方程: f[time][u]=∑f[time−1][v]f[time][u]=\sum f[time-1][v]f[time][u]=∑f[time−1 ...

  10. 2018.09.28 bzoj1563: [NOI2009]诗人小G(决策单调性优化dp)

    传送门 决策单调性优化dp板子题. 感觉队列的写法比栈好写. 所谓决策单调性优化就是每次状态转移的决策都是在向前单调递增的. 所以我们用一个记录三元组(l,r,id)(l,r,id)(l,r,id)的 ...