【问题标题】:Dotnet Core Multiple Startup Classes with In-Process Hosting具有进程内托管的 Dotnet Core 多个启动类
【发布时间】:2018-12-14 16:10:16
【问题描述】:

我有一个 dotnet core v.2.1 应用程序,它利用“startup-class-by-environment-name-convention”为不同的环境使用不同的Startup 类,例如开发、分期和生产。 Program.Main.CreateWebHost 方法看起来类似于:

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    var startupAssembly = Assembly.GetExecutingAssembly();
    var webHostBuilder = WebHost.CreateDefaultBuilder(args)
                                .UseStartup(startupAssembly.FullName);
    return webHostBuilder;
}

但是,在升级到 dotnet core v.2.2 之后(启动切换仍然很好用),我想尝试进程内托管功能。当切换到进程内托管模型,并在本地使用更新的 Visual Studio 2017 和 IIS Express 运行时,运行应用程序时出现以下错误:

HTTP 错误 500.30 - ANCM 进程中启动失败

此问题的常见原因:

  • 应用程序启动失败
  • 应用程序已启动,但随后 停止
  • 应用程序已启动,但在启动期间引发异常

故障排除步骤:

  • 检查系统事件日志中的错误消息
  • 启用记录应用程序进程的标准输出消息
  • 将调试器附加到应用程序进程并检查

欲了解更多信息,请访问:https://go.microsoft.com/fwlink/?LinkID=2028265

我检查了所有日志,我只能找到以下内容:

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="IIS Express AspNetCore Module V2" /> 
    <EventID Qualifiers="0">1007</EventID> 
    <Level>2</Level> 
    <Task>0</Task> 
    <Keywords>0x80000000000000</Keywords> 
    <TimeCreated SystemTime="2018-12-14T10:37:48.327935100Z" /> 
    <EventRecordID>3693</EventRecordID> 
    <Channel>Application</Channel> 
    <Computer>[whatever]</Computer> 
    <Security /> 
  </System>
  <EventData>
    <Data>Application '/LM/W3SVC/2/ROOT' with physical root '[whatever again]' failed to load clr and managed application. CLR worker thread exited prematurely</Data> 
    <Data>Process Id: 29836.</Data> 
    <Data>File Version: 12.2.18316.0. Description: IIS ASP.NET Core Module V2 Request Handler. Commit: ce8cf65589734f82b0536c543aba5bd60d0a5a98</Data> 
  </EventData>
</Event>

我阅读了所有 dotnet core in-hosting migrate 2.1 -> 2.2 任何我能找到的 MSDN 文章,并尝试了一堆不同的设置,但除了使用默认设置之外找不到任何解决方案:

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

... 这不行 - 我想将启动切换 together 与进程内托管一起使用。有谁知道如何实现这一点,或者对如何进行故障排除有任何建议?

编辑:我从@cilerler 那里得到了我需要的答案。为了完整起见,这就是我的情况:

我的自定义配置文件加载失败,因为此过程依赖于对 Directory.GetCurrentDirectory() 的调用,当切换到进程内托管时,结果会发生变化。这是我那部分的原始代码(为简洁起见):

var basePath = $"{Directory.GetCurrentDirectory()}\\ConfigurationFiles";
builder.SetBasePath(basePath);

builder.AddJsonFile("some.config.json", false, true);
builder.AddJsonFile($"some.config.{context.HostingEnvironment.EnvironmentName}.json", true, true);

关键部分是 - 再次 - 对 GetCurrentDirectory() 的调用,因此,为了解决这个问题,我根据接受的答案中的建议将上述内容更改为:

var currentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var basePath = $"{currentDirectory}\\ConfigurationFiles";
builder.SetBasePath(basePath);

有关更多详细信息,请参阅接受的答案;)

【问题讨论】:

    标签: c# .net-core iis-express-10


    【解决方案1】:

    根据aspnet-core-module文章说

    GetCurrentDirectory 返回由 IIS 启动的进程的工作目录,而不是应用程序的目录(例如,对于 w3wp.exe,C:\Windows\System32\inetsrv)。

    这意味着配置加载器将无法找到appsettings.* 文件或任何其他文件,例如依赖于GetCurrentDirectory 调用的自定义配置文件。为了在您的 Program.cs 中解决它public static void Main(string[] args) { 之后添加以下行

    Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
    

    另外,在项目文件(例如MyProject.csproj中确保您有以下几行并且appsettings.*存在于输出文件夹中。

    <ItemGroup>
      <Content Update="appsettings.json">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </Content>
      <Content Update="appsettings.Development.json">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </Content>
      <Content Update="appsettings.Production.json">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      </Content>
    </ItemGroup>
    

    【讨论】:

    • 这让我更进一步。我遇到了一些我能够解决的错误。但后来我又卡住了 :( 日志看起来不错,说明应用程序已启动,但 web api 没有响应,在 windows 应用程序日志中我有:加载 clr 和托管应用程序失败。托管服务器后未初始化120000 毫秒。如果我在 IIS 之外启动 dll,一切正常。:(我已经为 IIS 安装了 .net 核心模块,(v2)
    • 感谢您的回复。如果您要解释为什么您认为您的建议可能会有所帮助,以及它们与进程内托管方案的关系,您的回答可能会更有帮助。就我而言,我对配置文件没有任何问题,因此您建议的代码添加对手头的问题没有任何影响,很抱歉。
    • @OskarLindberg 更新了答案,您的设置可能有所不同,但我很确定这是问题所在,因为我收到的错误消息与您的完全相同。因此,如果您可以使用引发错误的代码库的简化版本创建存储库,我可以为您调查
    • 你是 100% 正确的!我只是以为我已经检查了配置文件是否已正确加载。我也完全偏离了轨道,因为应用程序使用“默认”CreateWebHostBuilder 代码启动得很好。不过,除了&lt;appsettings.json\&gt; 之外,我还加载了一些其他配置文件,并且由于调用Directory.GetCurrentDirectory() 的新结果,加载确实失败了,所以这条信息对于我理解这个问题至关重要。谢谢你:)
    【解决方案2】:

    我有同样的问题,不同的故事。

    Visual Studio 2017 - asp.net core mvc (sdk 2.2.104)。

    1. 运行应用程序。 (是的,它会再次给你错误)
    2. 在 VS 中转到异常设置并启用 C++ 异常、CLR 异常、Win32 异常
    3. 重新开始调试进程,看看是否抛出异常。

    在我的例子中:我通过 .AddScoped 在 Startup.cs 中注册了一个服务,其中具体的 serviceType 参数实际上是一个抽象类(重构后忘记更改它)。

    否则,请转到 Windows 事件查看器并尝试在日志中找到线索。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-11
      • 2018-04-12
      • 2020-03-22
      • 2019-12-10
      • 2020-10-11
      • 2022-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多