是否可以在Application _Start中获取主机?

时间:2015-03-24 19:35:47

标签: c# asp.net iis host

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

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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

  

是否可以在Application_Start()中找到正在使用的主机?

AFAIK不,不是。

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

System.Runtime.Caching是2种技术中较新的一种,它提供了一种抽象的ObjectCache类型,可以扩展为基于文件的类型。或者,有一个内置的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