Статьи

Отладка / Запуск приложения ASP.NET без Windows

Недавно пришел один из моих разработчиков .NET, который участвовал в проекте Windows Azure и задал мне два вопроса:

1. Почему для отладки или запуска проекта Windows Azure требуется больше времени, чем для обычного проекта ASP.NET? Отладка проекта Windows Azure занимает от 15 до 30 секунд, но отладка проекта ASP.NET — от 8 до 15 секунд.

Рисунок 1. Отладка проекта Windows Azure занимает больше времени, чем проект ASP.NET

Рисунок 1. Отладка проекта Windows Azure занимает больше времени, чем проект ASP.NET

2. Могу ли я отлаживать или запускать проект ASP.NET вместо проекта Windows Azure при разработке приложения Windows Azure?

Рисунок 2. Настройка веб-приложения ASP.NET в качестве стартового проекта.

Рисунок 2. Настройка веб-приложения ASP.NET в качестве стартового проекта.

Я смотрел онлайн-дискуссии по этим вопросам и нашел, что они очень популярные вопросы:

Эта статья ответит и объяснит эти два вопроса более подробно, включая, как это действительно работает под капотом, советы и хитрости, чтобы преодолеть проблему, и идентифицированные ограничения.

1. Почему для отладки или запуска проекта Windows Azure требуется больше времени, чем для обычного проекта ASP.NET?

Инструменты разработки Windows Azure и SDK

Прежде всего, мне нужно объяснить, как работают инструменты разработки Windows Azure и SDK.

Microsoft позволяет разработчикам создавать приложения .NET, ориентированные на Windows Azure, с помощью Windows Azure SDK (Software Development Kit) . SDK включает сборки, образцы, документацию, эмуляторы и инструменты командной строки для создания приложений Windows Azure.

Эмулятор предназначен для имитации облачной среды, поэтому разработчикам не нужно постоянно подключаться к облаку. Два эмулятора: эмулятор вычислений , имитирующий среду фабрики Azure, и эмулятор хранилищ , имитирующий хранилище Windows Azure. Помимо эмуляторов, двумя важными инструментами командной строки являются CSPack, который подготавливает и упаковывает приложение для развертывания, и CSRun, который развертывает приложение и управляет им локально. Другие инструменты командной строки можно найти здесь .

Помимо SDK, существует надстройка под названием Windows Azure Tools для Microsoft Visual Studio, которая расширяет Visual Studio 2010, позволяя создавать, настраивать, создавать, отлаживать, запускать, упаковывать и развертывать масштабируемые веб-приложения и службы в Windows Azure. Вы найдете новый «облачный» шаблон (как видно на рисунке 3) при добавлении нового проекта после его установки. Кроме того, он включает в себя сложность запуска инструментов и других команд за кулисами при создании, запуске и публикации проекта Windows Azure в Visual Studio.

Рисунок 3 - шаблон проекта Windows Azure

Рисунок 3 — шаблон проекта Windows Azure

Причина, почему это занимает больше времени

Это правда, что для отладки или запуска проекта Windows Azure требуется больше времени, чем для обычного проекта ASP.NET.

In fact there’s a reasonable rationale behind. When we debug or run a Windows Azure cloud project, all other associated projects (Web / Worker Role) will be compiled and packed into acsx directory. Afterwards, Visual Studio lets CSRun deploy and run your package. TheCompute Emulator will then set up and host your web applications in IIS as many as we specify in Instance Count property.

Рисунок 4 - Веб-сайты настраиваются в IIS при запуске проекта Windows Azure

Figure 4 – Websites are being set up in IIS when running Windows Azure Project

As the Full IIS capability was introduced in SDK 1.3, web applications on Windows Azure involve two processes: w3wp.exe which runs your actual ASP.NET application, and WaIISHost.exe which runs your RoleEntryPoint in WebRole.cs / WebRole.vb.

As can be seen, there’re more steps involved when debugging or running a Windows Azure Project. This explains why it takes longer to debug or run Windows Azure Project on Compute Emulator compared to debugging or running an ASP.NET project on IIS or ASP.NET Development Server (Cassini) which is more straightforward.

2. Can I debug or run the ASP.NET project instead of the Windows Azure Project when developing a Windows Azure Project?

Jumping into the next question, is it possible to debug or run ASP.NET project instead of Windows Azure project?

The answer is yes. You can do so simply by setting the ASP.NET project as startup project. However, there are some caveats:

1. Getting configuration settings from Windows Azure Service Configuration

People often store settings at ServiceConfiguration.cscfg in their Windows Azure Project. You can get the setting value by callingRoleEnvironment.GetConfigurationSettingValue(“Setting1”). However, you will run into an error when debugging or running the ASP.NET project.

Рисунок 5 - Ошибка при вызове RoleEnvironment.GetConfigurationSettingValue в проекте ASP.NET

Figure 5 – Error when calling RoleEnvironment.GetConfigurationSettingValue in ASP.NET Project

The reason of getting this error is because the ASP.NET project is unable to recognize and call GetConfigurationSettingValue as the settings belongs to Windows Azure Project.

The Resolution

To resolve this error, there’s a trick we can do as shown in the following code fragments. The idea is to encapsulate the retrieval settings using a get property. WithRoleEnvironment.IsAvailable, we are able to determine if the current runs on Windows Azure environment or a typical ASP.NET project. If it doesn’t run on Windows Azure environment, we can get the value from web.config instead of ServiceConfiguration.cscfg. Of course, we need to also store the setting somewhere else such as AppSettings in web.config file.

<code class="language-java">public string Setting1
{   get
 {   string setting1 = string.Empty;    if (RoleEnvironment.IsAvailable)   return RoleEnvironment.GetConfigurationSettingValue("Setting1").ToString();   else   return ConfigurationManager.AppSettings["Setting1"].ToString(); } } </code>

Code Fragment 1.1 – Encapsulating the setting with Get property

<code class="language-java"><Role name="AspNetWebApplication">  <Instances count="3" />  <ConfigurationSettings>   <Setting name="Setting1" value="running on Windows Azure environment" />  </ConfigurationSettings>
 </Role> </code>

Code Fragment 1.2 – Setting in ServiceConfiguration.cscfg

<code class="language-java"><appSettings>  <add key="Setting1" value="running as typical ASP.NET project"/>
 </appSettings>  </code>

Code Fragment 1.3 – Setting in web.config

2. Loading a storage account

We normally use the store the Storage Account Connection String in Service Configuration setting as well.

Рисунок 6 - Настройка строки подключения к хранилищу в конфигурации службы

Figure 6 – Setting Storage Connection String in Service Configuration

As such, you might run into similar error again when running the ASP.NET project.

The Resolution

We use similar technique to resolve, but slightly different API. If theRoleEnvironment.IsAvailable returns false, we will get the value from AppSetting in web.config. If we find that it uses Development Storage, we will loadCloudStorageAccount.DevelopmentStorageAccount, else we will parse the connection string that is loaded from AppSettings in web.config file. The following code fragments illustrate how you should write your code and configuration.

<code class="language-java">CloudStorageAccount storageAccount;
 if(RoleEnvironment.IsAvailable)
 storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
 else
 { string cs = ConfigurationManager.AppSettings["DataConnectionString "].ToString();
 if (cs.Equals("UseDevelopmentStorage=true"))
 storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
 else  storageAccount = CloudStorageAccount.Parse(cs);
 }
 </code>

Code Fragment 2.1 – Encapsulating the setting with get property

<code class="language-java"><appSettings>  <add key="DataConnectionString"
value="DefaultEndpointsProtocol=https;AccountName={name};AccountKey={key}"/>  <!--<add key="DataConnectionString" value="UseDevelopmentStorage=true"/>-->
 </appSettings> </code>

Code Fragment 2.2 – Setting in ServiceConfiguration.cscfg

<code class="language-java"><Role name="WebRole1">  <Instances count="1" />  <ConfigurationSettings>  <Setting name="DataConnectionString"
value="DefaultEndpointsProtocol=https;AccountName={name};AccountKey={key}" />
 <!-- <Setting name="DataConnectionString" value="UseDevelopmentStorage=true" />-->  </ConfigurationSettings>
 </Role> </code>

Code Fragment 2.3 – Setting in web.config

An important note: you will still need to turn on Windows Azure Storage Emulator when using this technique.

Catches and Limitations

Although these tricks work in most cases, there are several catches and limitations identified:

  • The technique is only applicable for ASP.NET Web Role, but not Worker Role.
  • Apart from two issues identified, logging with Windows Azure Diagnostic may not work. This may not be a serious concern as we are talking about the development phase, not in production.
  • You are unable to simulate multiple instances when debugging or running ASP.NET project.

Conclusion

To conclude, this article answers two questions.  We have identified some caveats as well as the tricks to overcome these issues.

Although this technique is useful to avoid debugging or running a Windows Azure Project, itdoesn’t mean you never need to run as a Windows Azure Project again. I would still recommend you occasionally run the Windows Azure Project to ensure that your ASP.NET project targets Windows Azure perfectly.

References