是否可以在Application_Start中获取host?

Is it possible to get the host in Application _Start?

我有一个绑定了多个主机名的网站。是否可以在 Application_Start() 中找出正在使用的主机?

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

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

// 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 的引用,即 available via NuGet

参考:http://blogs.msdn.com/b/carlosag/archive/2011/01/21/get-iis-bindings-at-runtime-without-being-an-administrator.aspx

Is it possible to find out in Application_Start() which host is being used?

AFAIK 不,不是。

根据您的评论,我认为您所追求的持久性机制是服务器端缓存选项之一 (System.Runtime.Caching or System.Web.Caching)。

System.Runtime.Caching 是这两种技术中较新的一种,它提供了一种抽象的 ObjectCache type that could potentially be extended to be file-based. Alternatively, there is a built-in MemoryCache 类型。

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

可以在第一次访问时填充缓存(大概是在请求已经填充之后,而不是在Application_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);

如果它很重要,您可以使用类似于 Micro Caching in ASP.NET 的锁定策略(或者只是批发使用该解决方案),这样当缓存过​​期时数据源不会收到多个请求。

此外,您可以指定项目是 "Not Removable",这将使它们在应用程序池重新启动时继续存在。

更多信息:http://bartwullems.blogspot.com/2011/02/caching-in-net-4.html