ABP在MultipleDbContext也就是多库的场景下发布后异常“Could not find content root folder”问题处理
ABP多库支持
ABP支持多库的方案在abp的案例中aspnetboilerplate-samples中给了现成的demo,其中MultipleDbContextDemo是EF的相关针对dotnet的版本,MultipleDbContextEfCoreDemo则是dotnet core版本的多库方案
按照改demo的思路,添加我们的abp的多库支持,F5直接允许,一切ok,欣慰,没有报错。
按照业务要求,完成代码一切美美哒。
ABP多库发布后异常
发布正式环境,请求访问第二个数据库的相关接口,抛出“应用程序内部错误的异常”
查看唯一App_Data目录下的日志文件 发现抛出异常,“Could not find content root folder”
然后就是各种bing,百度,google一通搜,没有找到结果。
问题查找调试
本地发布了一个和正式环境一样的环境,手动去调试一下,想追到是什么地方抛出来的,找到我们应用的进程(dotnet core下不是W3W了,而是你应用的dll名称)。附加到进程,发现我擦怎么进不了断点,换个接口试一下,发现依旧进不来断点。
测试发现附加的时候比之前多了一个选择,有个coreCLR的选择如下图,不知道这个玩意是什么鬼,先去掉吧,点击选择,选中“自动选择要调试的代码类型”。然后再来附加,进断点了,为啥呢,没有深究!

接下来继续排除我们的多库报错问题
跟代码发现异常是从Core下面的WebContentDirectoryFinder.cs抛出来的,如下图

找到问题源头了,我们就看怎么怎么解决,看一下当前代码干了什么事情。
public static string CalculateContentRootFolder()
{
var coreAssemblyDirectoryPath = Path.GetDirectoryName(typeof(AiCoreModule).GetAssembly().Location);
if (coreAssemblyDirectoryPath == null)
{
throw new Exception("Could not find location of Chemical.Ai.Core assembly!");
} DirectoryInfo directoryInfo = new DirectoryInfo(coreAssemblyDirectoryPath);
while (!DirectoryContains(directoryInfo.FullName, "Chemical.Ai.sln"))
{
//发布状态下,应该为当前目录
if (directoryInfo.Parent == null)
{
return coreAssemblyDirectoryPath;
//throw new Exception($"Could not find content root folder!");
} directoryInfo = directoryInfo.Parent;
} var webMvcFolder = Path.Combine(directoryInfo.FullName, "src", "Chemical.Ai.Web.Mvc");
if (Directory.Exists(webMvcFolder))
{
return webMvcFolder;
} var webHostFolder = Path.Combine(directoryInfo.FullName, "src", "Chemical.Ai.Web.Host");
if (Directory.Exists(webHostFolder))
{
return webHostFolder;
} throw new Exception("Could not find root folder of the web project!");
} private static bool DirectoryContains(string directory, string fileName)
{
return Directory.GetFiles(directory).Any(filePath => string.Equals(Path.GetFileName(filePath), fileName));
}
代码翻译:当前代码就是从dll的所在目录一层层找,直到找到解决方案文件所在的目录,然后将解决方案所在的目录的上层目录(A)返回给下面的逻辑使用。而下面的逻辑就是从上层目录A开始往下找到src下面的mvc或者host目录,
也就是我们的应用启动目录,返回appsettings.json所在的目录。
异常原因:在F5的调试状态下,appsettings.json是位于mvc或host下面的。但是当我们发布后,appsettings.json就是当前启动目录了,dll和appsettings.json是并列的级别
,我们在发布状态下,根本没有解决方案,所以根据解决方案找appsettings.json的方案行不通,也就会抛出我们看到的异常。
解决方案:发布状态下,无需如此复杂的逻辑,直接返回程序运行目录就可以了,如下图

修改完成发布,运行,异常没有了,程序完美运行!
ABP在MultipleDbContext也就是多库的场景下发布后异常“Could not find content root folder”问题处理的更多相关文章
- 如何使用开源库,吐在VS2013发布之前,顺便介绍下VS2013的新特性"Bootstrap"
刚看到Visual Studio 2013 Preview - ASP.NET, MVC 5, Web API 2新功能搶先看 看了下VS2013带来的"新特性",直觉上看,除了引 ...
- Oracle主库归档丢失,备库日志有gap,在不重建备库的情况下,恢复备库
本文主要描述Oracle备库日志与主库日志之间有gap,切主库这部分gap的归档日志已经删除或丢失,如何在不重建备库的情况下,恢复备库. 欢迎转载,请注明作者.出处. 作者:张正 blog:http: ...
- boost库在windows下的编译和使用
因为跨平台的原因,现在要使用到boost库,boost库非常大,现在处于摸索阶段. 首先来说boost库在window下的安装和使用. 一.下载 首先从boost官方主页http://www.boos ...
- 如何使用开源库,吐在VS2013发布之前,顺便介绍下V2013的新特性"Bootstrap"
如何使用开源库,吐在VS2013发布之前,顺便介绍下VS2013的新特性"Bootstrap" 刚看到Visual Studio 2013 Preview - ASP.NET, M ...
- C++标准库第二版笔记 3 和异常的理解 1
C++标准库第二版笔记 3 和异常的理解 1 差错和异常(error and exception)的处理 标准异常类(exception class) 定义于 分为: 1.语言本身支持的异常 2.标准 ...
- wxWidgets与其他工具库的比较(下)
2009-07-25 12:37:51 GTK+ ● GTK+的网站:www.gtk.org: ● GTK+原本是Gimp的一个工具库,是在LGPL协议下发布的Unix系统GU ...
- CPPCMS库在Windows下的使用
标题:CPPCMS库在Windows下的使用时间:2012-7作者:Kagula 环境:[1]WinXP SP3[2]VisualStudio2008 SP1[3]ZLib 1.2.7[4]PCRE ...
- C语言静态库与动态库(Windows下测试)
转载于:https://zhidao.baidu.com/question/1946953913764139388.html,原文为Linux上测试,本文为在Windows上编译测试 我们通常把一些公 ...
- < python音频库:Windows下pydub安装配置、过程出现的问题及常用API >
< python音频库:Windows下pydub安装配置.过程出现的问题及常用API > 背景 刚从B站上看过倒放挑战之后也想体验下,心血来潮一个晚上完成了基本的实现.其中倒放与播放部分 ...
随机推荐
- Linux下配置 Keepalived(心跳检测部署)
首先呢,我想先给大家简单介绍一下什么是keepalived: Keepalived的作用是检测服务器的状态,如果有一台web服务器死机,或工作出现故障,Keepalived将检测到,并将有故障的服务器 ...
- Myeclipse运行提示错误: 找不到或无法加载主类 test.test1 终极解决办法
前提是代码没有问题 简单粗暴的解决办法: 重启电脑 解决办法2: 1.在控制台中点开“Problems”,查看里面的错误.如果是多个项目,可以将其他项目暂时关闭. 根据错误进行处理. 2.把项目cle ...
- oralce update操作
1.基本语法:update 表名 set 列名=表达式 [列名=表达式. . . ] where 条件 2.使用的注意事项: v UPDATE语法可以用新值更新原有表行中的各列 把zs的性别改为女 ...
- hihocoder 1586 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛-题目9 : Minimum【线段树】
https://hihocoder.com/problemset/problem/1586 线段树操作,原来题并不难..... 当时忽略了一个重要问题,就是ax*ay要最小时,x.y可以相等,那就简单 ...
- Tcp之双向通信
TestServer.java package com.sxt.tcp; /* * 服务端 */ import java.io.DataInputStream; import java.io.Data ...
- Collections.sort list内部排序
public class ComparatorUser implements Comparator{ public int compare(Object arg0, Object arg1) { ...
- Docker 领衔 OpenSource.com 2014十佳开源软件排行榜
Docker 领衔 OpenSource.com 2014十佳开源软件排行榜 每年 Opensource.com 都会收集最佳的十个开源软件,今年也不例外,废话不多说,直接进入主题. Docker 应 ...
- 对装饰器@wraps的解释(一看就懂)-- 并对装饰器详解
1. 先看一段代码 def is_login(func): def foo(*args,**kwargs): return func(*args,**kwargs) return foo def te ...
- Java 对象序列化机制详解
对象序列化的目标:将对象保存到磁盘中,或允许在网络中直接传输对象. 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久的保存在磁盘上,通过网络将这种二进制流传 ...
- C#循环语句练习(二)
1.求1!+2!+...+n! 所有阶乘的和 2.求100以内的质数 (1)第一种做法 (2)另一种做法 3. 总数=幼兔+小兔+成兔成兔=上个月的小兔+上个月的成兔小兔=上个月的幼兔幼兔=这个月的成 ...