如何检测ASP.NET站点是在本地,azure Web角色还是azure网站上运行?

时间:2014-11-30 23:58:47

标签: asp.net-mvc azure azure-web-roles azure-web-sites

注意:这与检测本地运行和Azure角色的问题不同,我理解已经回答了这个问题。

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

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

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

RoleEnvironment.IsAvailable

然而,这对我的需求来说似乎是一个不完整的解决方案。它似乎检测代码是在本地运行还是作为Web角色运行没有问题。但是,似乎没有涵盖检查作为天蓝色网站运行的情况。它不仅没有涵盖这一点,而且在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)

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

2 个答案:

答案 0 :(得分:4)

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

有关详细信息,请参阅this answer

答案 1 :(得分:1)

如果您使用的是Azure,Azure模拟器,IIS或本地运行的集成测试,那么让我为您提供另一种方法。这很重要,因为在IIS中调试最有用且速度更快的表达最终将在Azure中运行的纯Web项目或运行甚至可能在IIS之外运行的集成测试。这意味着您可以更快地调试项目,而不是每次都浪费所有时间加载/运行azure计算模拟器。

有几种方法可以检查这个和那个但是这里有另一种方法可以帮助你在所有情况下移动以进行良好的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
  5. 问题在于:如果您尝试在IIS中访问RoleEnvironment.IsAvailable或RoleEnvironment.IsEmulated而不在模拟器或Azure中运行 - 您将获得异常。在Azure模拟器中,如果环境尚未就绪,IIS也将获得异常 - 模拟器和IIS一起运行,即使您在访问Global.asax.cs之前通过RoleEntryPoint,IIS也不会等待模拟器。这个“东西”消除了等待的可能性

      while(!RoleEnvironment.IsAvailable)
    

    快速清理问题。此问题还消除了RoleEnvironment.IsEmulated的使用,因为它将在本地IIS或本地集成测试中引发异常,并且无法在它之前检查RoleEnvironment.IsAvailable,因为如果您等待它在Azure或Azure模拟器之外准备就绪你会等待那里的东西。

    附注:有时在模拟器环境中可以加载,然后您的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中运行代码 - 例如将旧数据库的版本从已退役的WEB版本更新到IDatabaseInitializer的自定义实现中的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&amp;&amp;!RoleEnvironment.IsEmulated) 就够了。 如果有人知道如何使两者按照确切的顺序发生并分享它 - 那就太好了。

相关问题