简体   繁体   English

在 aspnet core 运行时检查托管服务器是 IIS 还是 Kestrel

[英]Check if hosting server is IIS or Kestrel at runtime in aspnet core

I'm currently running my application under either Kestrel (locally) or IIS InProcess (production).我目前正在 Kestrel(本地)或 IIS InProcess(生产)下运行我的应用程序。

return WebHost.CreateDefaultBuilder(args)
    .ConfigureKestrel(options => options.AddServerHeader = false)
    .UseIIS()
    .UseStartup<Startup>();

I'd like to be able to get the hosting server name at runtime in a controller so I can achieve the following:我希望能够在运行时在控制器中获取托管服务器名称,以便实现以下目标:

if (hostingServer == "kestrel")
{
    DoSomething();
}
else
{
    DoSomethingElse();
}

In this specific case it's to get around the fact that non-ascii characters are not supported in response headers with Kestrel.在这种特定情况下,它是为了解决这样一个事实,即 Kestrel 的响应标头中不支持非 ascii 字符。 Ideally I would remove the non-ascii header but currently it's required for legacy interoperability.理想情况下,我会删除非 ascii 标头,但目前它是遗留互操作性所必需的。

Any help would be massively appreciated.任何帮助将不胜感激。

The easiest way is probably reading System.Diagnostics.Process.GetCurrentProcess().ProcessName .最简单的方法可能是阅读System.Diagnostics.Process.GetCurrentProcess().ProcessName If it is w3wp or iisexpress you know the host is IIS/IIS Express, while dotnet (or other names when you use self-contained deployment) indicates Kestrel.如果它是w3wpiisexpress ,则您知道主机是 IIS/IIS Express,而dotnet (或其他名称,当您使用独立部署时)表示 Kestrel。 This will only work for an in process deployment.这仅适用于进程中的部署。 If you are out of process, this will not work.如果您不在流程中,这将不起作用。 Learn more at https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/aspnet-core-modulehttps://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/aspnet-core-module了解更多信息

Example:例子:

/// <summary>
/// Check if this process is running on Windows in an in process instance in IIS
/// </summary>
/// <returns>True if Windows and in an in process instance on IIS, false otherwise</returns>
public static bool IsRunningInProcessIIS()
{
    if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
        return false;
    }

    string processName = Path.GetFileNameWithoutExtension(Process.GetCurrentProcess().ProcessName);
    return (processName.Contains("w3wp", StringComparison.OrdinalIgnoreCase) ||
        processName.Contains("iisexpress", StringComparison.OrdinalIgnoreCase));
}

Checking for process name didn't work for me, even when hosting in IIS with InProcess it still proxies to the dotnet process (my guess is that you would need to get parent process to get the w3wp process).检查进程名称对我不起作用,即使在 IIS 中使用 InProcess 托管时它仍然代理dotnet进程(我的猜测是您需要获取父进程才能获取 w3wp 进程)。

Internally .NET Core calls IsAspNetCoreModuleLoaded() in NativeMethods.cs as can be found in WebHostBuilderIISExtensions.cs . .NET Core 在内部调用NativeMethods.cs中的IsAspNetCoreModuleLoaded() ,这可以在WebHostBuilderIISExtensions.cs中找到。 So checking for IIS can be done with the following code.因此可以使用以下代码检查 IIS。

internal static class NativeMethods
{
    internal const string AspNetCoreModuleDll = "aspnetcorev2_inprocess.dll";

    [DllImport("kernel32.dll")]
    private static extern IntPtr GetModuleHandle(string lpModuleName);

    public static bool IsAspNetCoreModuleLoaded()
    {
        return GetModuleHandle(AspNetCoreModuleDll) != IntPtr.Zero;
    }
}

When the application starts the hosting method can be exposed in IApplicationBuilder.ServerFeatures .当应用程序启动时,可以在IApplicationBuilder.ServerFeatures中公开托管方法。 Through here you can find items that reference Kestrel vs reverse proxy configuration.通过此处,您可以找到引用 Kestrel 与反向代理配置的项目。

The IApplicationBuilder available in the Startup.Configure method exposes the ServerFeatures property of type IFeatureCollection. Startup.Configure 方法中可用的 IApplicationBuilder 公开 IFeatureCollection 类型的 ServerFeatures 属性。 Kestrel and HTTP.sys only expose a single feature each, IServerAddressesFeature, but different server implementations may expose additional functionality. Kestrel 和 HTTP.sys 仅公开一个功能,即 IServerAddressesFeature,但不同的服务器实现可能会公开其他功能。 IServerAddressesFeature can be used to find out which port the server implementation has bound at runtime. IServerAddressesFeature 可用于找出服务器实现在运行时绑定了哪个端口。

The property is a collection, so you'll need to filter for specific hosting methods that pertain to IIS Reverse Proxy and Kestrel.该属性是一个集合,因此您需要筛选与 IIS 反向代理和 Kestrel 相关的特定托管方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM