【问题标题】:How to detect if ASP.NET site is running locally, in azure web role, or azure web site?如何检测 ASP.NET 站点是否在本地运行、以 azure web 角色或 azure web 站点运行?
【发布时间】:2015-01-28 22:49:38
【问题描述】:

注意:这与检测本地运行还是以 Azure 角色运行的问题不同,据我所知,这个问题已经得到解答。

我有一个部署到 Azure 的 APS.NET MVC 应用程序。我正在运行 Azure 工具的 V2.5。我希望能够检测代码运行在以下三种场景中的哪一种:

本地(在 IIS 上调试)、Azure 网站或 Azure Web 角色

我在其他帖子中看到了使用以下内容的建议:

RoleEnvironment.IsAvailable

但是,对于我的需求,这似乎是一个不完整的解决方案。它似乎可以检测代码是在本地运行还是作为 Web 角色运行而没有问题。但是,它似乎没有涵盖检查是否作为 azure 网站运行的场景。它不仅没有涵盖这一点,而且在 Azure 网站上运行时尝试检查该属性会导致它崩溃:

在 mscorlib.dll 中发生了“System.IO.FileLoadException”类型的第一次机会异常

Additional information: Could not load file or assembly
'Microsoft.WindowsAzure.ServiceRuntime, Version=2.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies.
The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

那么,谁能告诉我如何在这三种情况之间进行检测?

【问题讨论】:

    标签: asp.net-mvc azure azure-web-roles azure-web-app-service


    【解决方案1】:

    让我为您提供另一种方法,让您知道您是在 Azure、Azure Emulator、IIS 还是在本地运行集成测试。这一点很重要,因为在 IIS 中调试表示最终将在 Azure 中运行的纯 Web 项目或运行甚至可能在 IIS 之外运行的集成测试是有用且更快的。这意味着您可以更快地调试项目,而不是每次都浪费时间加载/运行天蓝色计算模拟器。

    有几种方法可以检查这个和那个,但这里有另一种方法可以帮助您在所有情况下移动以获得良好的 ALM 和开发。

    您有四种可用的机制可供使用:

    1. IIS 中的 HostingEnvironment 对象
    2. Azure 或 Azure 模拟器中的 RoleEnvironment 对象
    3. System.Environment 对象随处可见。
    4. 配置 - 在我的例子中是 web.config、web.debug.config、web.release.config、web.debug.staging.config、web.release.production.config、app.config、ServiceConfiguration.Local.cscfg、 ServiceConfiguration.CloudStaging.cscfg 和 ServiceConfiguration.CloudProduction.cscfg

    问题在于:如果您尝试在 IIS 中访问 RoleEnvironment.IsAvailable 或 RoleEnvironment.IsEmulated 而不在 Emulator 或 Azure 中运行 - 您将收到异常。如果环境尚未准备好,在带有 IIS 的 Azure 模拟器中也会出现异常 - 模拟器和 IIS 一起运行并且 IIS 不会等待模拟器,即使您在到达 Global.asax.cs 之前通过了 RoleEntryPoint。这个“东西”消除了像那样等待的可能性

      while(!RoleEnvironment.IsAvailable)
    

    并快速干净地解决问题。此问题还消除了 RoleEnvironment.IsEmulated 的使用,因为它会在本地 IIS 或本地集成测试中引发异常,并且无法在它之前检查 RoleEnvironment.IsAvailable,因为如果您等待它在 Azure 或 Azure Emulator 之外准备好你会等待即将出现的东西。

    旁注:有时在模拟器环境中可以稍后加载,然后您的 MVC 项目和访问 RoleEnvironment 属性会引发异常。这可以通过调用

    来轻松缓解
     while(!RoleEnvironment.IsAvailable)
    

    旁注结束。

    附注 2 像这样在 RoleEntryPoint 中设置环境变量:

    public class WebRole : RoleEntryPoint
    {
        public override bool OnStart()
        {
            Environment.SetEnvironmentVariable("CodeRunsInAzure","true");
        }
    }
    

    不会工作,因为they run in different places 并且您无法像那样检索它:

    Environment.GetEnvironmentVariable("CodeRunsInAzure")
    

    在 Global.asax.cs 或您的 Web/Worker 项目的其他地方。否则问题很容易解决。

    旁注 2 结束。

    解决方案分为两部分。第一个在您的配置文件中。只需在需要它的所有配置中设置变量 - *.cscfgs :

    <Setting name="RunsInAzureCloudEnv" value="true/false"/>
    

    在 ServiceConfiguration.Local.cscfg - false 和 cscfg 中的其他任何地方 - true。然后在 web.*.config / app.config 中相应地

    <add key="RunsInAzureCloudEnv" value="true/false"/>
    

    这样变量只会在您发布或在模拟器中运行时设置为 true,否则将为 false。

    使用此功能的一种情况是您只想在 azure 中运行代码 - 例如在您的 IDatabaseInitializer 自定义实现中将旧数据库的版本从已停用的 WEB 版本更新为 BASIC。在这种情况下,您只需要在 Azure 中运行您的代码,并且仅当它不在模拟器中而是在您的暂存或生产环境中运行。示例用法如下:

    // check the variable that is set only in azure environment
    var runsInAzureEnvStr = CloudConfigurationManager.GetSetting("RunsInAzureCloudEnv");
    bool runsInAzureEnv = false;
    Boolean.TryParse(runsInAzureEnvStr, out runsInAzureEnv);
    
    if(!runsInAzureEnv)
    {
        return;
    }   
    

    如果只有模拟器在 MVC 启动之前准备好: if(RoleEnvironment.IsAvailable && !RoleEnvironment.IsEmulated) 就够了。 如果有人知道如何让这两者以准确的顺序发生并分享——那就太好了。

    【讨论】:

      【解决方案2】:

      我遇到的确定您是否在 Azure 网站上运行的最佳方法是检查是否存在特定于 Azure 网站的环境变量,例如 WEBSITE_SITE_NAME。你可以先检查一下,如果变量不存在,继续RoleEnvironment.IsAvailable检查。

      请参阅this answer 了解更多详情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-10-24
        • 2012-12-25
        • 1970-01-01
        • 1970-01-01
        • 2016-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多