C# 可以让主机进入应用程序启动吗?

C# 可以让主机进入应用程序启动吗?,c#,asp.net,iis,host,C#,Asp.net,Iis,Host,我有一个绑定了多个主机名的网站。是否可以在应用程序_Start()中找到正在使用的主机 我知道目前我没有请求,所以我想可能没有,但是我知道访问应用程序的每个主机都将在新的应用程序池下运行。所以我想知道IIS中是否有我可以查询的内容,可以告诉我当前应用程序池使用的是什么主机名?好吧,IIS不是域权限,因此只有手动保持本地设置和DNS设置同步,才能读取IIS设置。但是有一种方法可以读取IIS绑定。因此,如果在IIS配置中使用主机头名称,则可以有效地读取域名 // Get the current Si

我有一个绑定了多个主机名的网站。是否可以在应用程序_Start()中找到正在使用的主机


我知道目前我没有请求,所以我想可能没有,但是我知道访问应用程序的每个主机都将在新的应用程序池下运行。所以我想知道IIS中是否有我可以查询的内容,可以告诉我当前应用程序池使用的是什么主机名?

好吧,IIS不是域权限,因此只有手动保持本地设置和DNS设置同步,才能读取IIS设置。但是有一种方法可以读取IIS绑定。因此,如果在IIS配置中使用主机头名称,则可以有效地读取域名

// Get the current Site Name
var siteName = HostingEnvironment.SiteName;

// Get the sites section from the AppPool.config
var sitesSection = WebConfigurationManager.GetSection(null, null, "system.applicationHost/sites");

var site = sitesSection.GetCollection().Where(x => string.Equals((string)x["name"], siteName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

if (site != null)
{
    foreach (var iisBinding in site.GetCollection("bindings"))
    {
        var protocol = iisBinding["protocol"] as string;
        var bindingInfo = iisBinding["bindingInformation"] as string;

        string[] parts = bindingInfo.Split(':');
        if (parts.Length == 3)
        {
            //string ip = parts[0]; // May be "*" or the actual IP
            //string port = parts[1]; // Always a port number (even if default port)
            string hostHeader = parts[2]; // May be a host header or "". This will only be the domain name if you keep it in sync with the DNS.

            // Use the hostHeader as the domain name
        }
    }
}
要使其工作,您需要设置对Microsoft.Web.Administration.dll的引用,即


参考资料:

嗯,IIS不是域权限,因此只有在手动保持本地设置和DNS设置同步的情况下,才能读取IIS设置。但是有一种方法可以读取IIS绑定。因此,如果在IIS配置中使用主机头名称,则可以有效地读取域名

// Get the current Site Name
var siteName = HostingEnvironment.SiteName;

// Get the sites section from the AppPool.config
var sitesSection = WebConfigurationManager.GetSection(null, null, "system.applicationHost/sites");

var site = sitesSection.GetCollection().Where(x => string.Equals((string)x["name"], siteName, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

if (site != null)
{
    foreach (var iisBinding in site.GetCollection("bindings"))
    {
        var protocol = iisBinding["protocol"] as string;
        var bindingInfo = iisBinding["bindingInformation"] as string;

        string[] parts = bindingInfo.Split(':');
        if (parts.Length == 3)
        {
            //string ip = parts[0]; // May be "*" or the actual IP
            //string port = parts[1]; // Always a port number (even if default port)
            string hostHeader = parts[2]; // May be a host header or "". This will only be the domain name if you keep it in sync with the DNS.

            // Use the hostHeader as the domain name
        }
    }
}
要使其工作,您需要设置对Microsoft.Web.Administration.dll的引用,即

参考:

是否可以在应用程序_Start()中找到正在使用的主机

哎呀,不,不是

根据您的评论,我认为您所追求的持久化机制是服务器端缓存选项(or)之一

System.Runtime.Caching
是这两种技术中较新的一种,它提供了一种抽象类型,可以扩展为基于文件的。或者,有一个内置类型

与使用静态方法不同,缓存将基于超时(固定或滚动)为所有用户(和所有域)保持状态,并且可能具有导致缓存立即失效的缓存依赖项。一般的想法是在缓存过期后从存储(文件或数据库)重新加载数据。缓存保护存储不被每个请求命中-只有在达到超时或缓存无效后才会命中存储

您可以在首次访问缓存时填充缓存(可能是在已填充请求之后,而不是在
应用程序\u Start
事件中),并使用域名作为用于查找数据的缓存键的一部分(或全部)

public DataType GetData(string domainName)
{
    // Use the domain name as the key (or part of the key)
    var key = domainName;

    // Retrieve the data from the cache (System.Web.Caching shown)
    DataType data = HttpContext.Current.Cache[key];
    if (data == null)
    {
        // If the cached item is missing, retrieve it from the source
        data = GetDataFromDataSource();

        // Populate the cache, so the next request will use cached data

        // Note that the 3rd parameter can be used to specify a 
        // dependency on a file or database table so if it is updated, 
        // the cache is invalidated
        HttpContext.Current.Cache.Insert(
            key, 
            data, 
            null, 
            System.Web.Caching.Cache.NoAbsoluteExpiration, 
            TimeSpan.FromMinutes(10), 
            System.Web.Caching.CacheItemPriority.NotRemovable);
    }

    return data;
}

// Usage
var data = GetData(HttpContext.Current.Request.Url.DnsSafeHost);
如果这很重要,您可以使用与类似的锁定策略(或者只使用该解决方案),以便在缓存过期时数据源不会收到多个请求

此外,您可以指定项是“不可移动的”,这将使它们在应用程序池重新启动时继续存在

更多信息:

是否可以在应用程序_Start()中找到正在使用的主机

哎呀,不,不是

根据您的评论,我认为您所追求的持久化机制是服务器端缓存选项(or)之一

System.Runtime.Caching
是这两种技术中较新的一种,它提供了一种抽象类型,可以扩展为基于文件的。或者,有一个内置类型

与使用静态方法不同,缓存将基于超时(固定或滚动)为所有用户(和所有域)保持状态,并且可能具有导致缓存立即失效的缓存依赖项。一般的想法是在缓存过期后从存储(文件或数据库)重新加载数据。缓存保护存储不被每个请求命中-只有在达到超时或缓存无效后才会命中存储

您可以在首次访问缓存时填充缓存(可能是在已填充请求之后,而不是在
应用程序\u Start
事件中),并使用域名作为用于查找数据的缓存键的一部分(或全部)

public DataType GetData(string domainName)
{
    // Use the domain name as the key (or part of the key)
    var key = domainName;

    // Retrieve the data from the cache (System.Web.Caching shown)
    DataType data = HttpContext.Current.Cache[key];
    if (data == null)
    {
        // If the cached item is missing, retrieve it from the source
        data = GetDataFromDataSource();

        // Populate the cache, so the next request will use cached data

        // Note that the 3rd parameter can be used to specify a 
        // dependency on a file or database table so if it is updated, 
        // the cache is invalidated
        HttpContext.Current.Cache.Insert(
            key, 
            data, 
            null, 
            System.Web.Caching.Cache.NoAbsoluteExpiration, 
            TimeSpan.FromMinutes(10), 
            System.Web.Caching.CacheItemPriority.NotRemovable);
    }

    return data;
}

// Usage
var data = GetData(HttpContext.Current.Request.Url.DnsSafeHost);
如果这很重要,您可以使用与类似的锁定策略(或者只使用该解决方案),以便在缓存过期时数据源不会收到多个请求

此外,您可以指定项是“不可移动的”,这将使它们在应用程序池重新启动时继续存在


更多信息:

您想实现什么?@JohnSaunders我有一个应用程序的代码库,但我有多个客户在不同的主机名下使用此应用程序。当一个请求进来时,我会得到他们的配置信息。这没什么大不了的,因为它被放入一个静态变量中,如果它被设置了,我就不会再设置它。但我只是好奇,是否有一种方法可以在应用程序启动时执行此操作,因为理论上我应该拥有执行此操作所需的所有信息。你想实现什么?@JohnSaunders我有一个应用程序的代码库,但我有多个客户以不同的主机名使用此应用程序。当一个请求进来时,我会得到他们的配置信息。这没什么大不了的,因为它被放入一个静态变量中,如果它被设置了,我就不会再设置它。但我只是好奇是否有一种方法可以在应用程序启动时执行,因为理论上我应该拥有执行此操作所需的所有信息。。。但我如何知道调用代码与哪一个关联呢?很好。我假设您将每个应用程序作为不同的IIS站点托管,因此定位它只需使用StartsWith或RegEx找到正确的绑定字符串。但是如果你在同一个网站上托管所有的域名,这就行不通了。我已经为你的问题想出了一个更好的解决方案,并添加了另一个答案,但这个答案仍然可能对某人有所帮助