Приложение. Пример приложения Fix It (создание Real-World облачных приложений с помощью Azure)

Рик Андерсон(Rick Anderson),Том Дайкстра (Tom Dykstra)

Скачивание проекта Fix It

Электронная книга Building Real World Cloud Apps with Azure (Создание реальных облачных приложений с помощью Azure ) основана на презентации, разработанной Скоттом Гатри. В ней описано 13 шаблонов и методик, которые помогут вам успешно разрабатывать веб-приложения для облака. Сведения об электронной книге см. в первой главе.

Это приложение к электронной книге Building Real World Cloud Apps with Azure (Создание реальных облачных приложений с помощью Azure) содержит следующие разделы, содержащие дополнительные сведения о примере приложения Fix It, которое можно скачать:

Известные проблемы

Приложение Fix It было первоначально разработано для того, чтобы как можно более просто проиллюстрировать некоторые шаблоны, представленные в этой электронной книге. Тем не менее, так как электронная книга посвящена созданию реальных приложений, мы подвергли код Fix It процессу проверки и тестирования, аналогичному тому, что мы делаем для выпущенного программного обеспечения. Мы обнаружили ряд проблем, и, как и в случае с любым реальным приложением, некоторые из них мы исправили, а некоторые мы отложили до последующего выпуска.

В следующем списке перечислены проблемы, которые должны быть устранены в рабочем приложении, но по той или иной причине мы решили не решать в первоначальном выпуске примера приложения Fix It.

Безопасность

  • Убедитесь, что вы не можете назначить задачу несуществующему владельцу.
  • Убедитесь, что вы можете просматривать и изменять только созданные или назначенные вам задачи.
  • Используйте HTTPS для страниц входа и файлов cookie проверки подлинности.
  • Укажите ограничение времени для файлов cookie проверки подлинности.

Проверка ввода

Как правило, рабочее приложение будет выполнять больше проверки входных данных, чем приложение Fix It. Например, размер изображения или размер файла изображения, разрешенный для отправки, должен быть ограничен.

Функции администратора

Администратор должен иметь возможность изменить владельца существующих задач. Например, создатель задачи может покинуть компанию, не предоставив никому полномочий на обслуживание задачи, если не включен административный доступ.

Обработка сообщений очереди

Обработка сообщений очереди в приложении "Исправление" была разработана как простая, чтобы проиллюстрировать шаблон работы, ориентированный на очередь, с минимальным объемом кода. Этот простой код не подходит для фактического рабочего приложения.

  • Код не гарантирует, что каждое сообщение очереди будет обрабатываться не более одного раза. При получении сообщения из очереди существует период ожидания, в течение которого сообщение становится невидимым для других прослушивателей очереди. Если время ожидания истекает до удаления сообщения, сообщение снова становится видимым. Таким образом, если экземпляр рабочей роли тратит много времени на обработку сообщения, теоретически возможно, что одно и то же сообщение будет обработано дважды, что приведет к дублированию задачи в базе данных. Дополнительные сведения об этой проблеме см. в статье Использование очередей службы хранилища Azure.
  • Логика опроса очередей может быть более экономичной за счет пакетного извлечения сообщений. При каждом вызове CloudQueue.GetMessageAsync возникает стоимость транзакции. Вместо этого можно вызвать CloudQueue.GetMessagesAsync (обратите внимание на множественное число "s"), который получает несколько сообщений в одной транзакции. Затраты на транзакции для очередей службы хранилища Azure очень низкие, поэтому в большинстве сценариев влияние на затраты не является существенным.
  • Узкий цикл в коде обработки сообщений очереди вызывает сходство ЦП, что не позволяет эффективно использовать многоядерные виртуальные машины. Более лучшая конструкция позволит использовать параллелизм задач для параллельного выполнения нескольких асинхронных задач.
  • Обработка сообщений очереди имеет только рудиментную обработку исключений. Например, код не обрабатывает подозрительные сообщения. (Если обработка сообщения вызывает исключение, необходимо записать ошибку в журнал и удалить сообщение, иначе рабочая роль попытается обработать его снова, и цикл будет продолжаться бесконечно.)

Запросы SQL являются неограниченными

Текущее исправление. Код не устанавливает ограничений на количество строк, возвращаемых запросами для страниц индекса. Если в базу данных вводится большой объем задач, размер полученных списков может привести к проблемам с производительностью. Решение заключается в реализации разбиения по страницам. Пример см. в разделе Сортировка, фильтрация и разбиение на страницы с помощью Entity Framework в приложении ASP.NET MVC.

Приложение Fix It использует класс сущностей FixItTask для передачи информации между контроллером и представлением. Рекомендуется использовать модели представлений. Модель предметной области (например, класс сущностей FixItTask) предназначена для обеспечения сохраняемости данных, а модель представления может быть разработана для представления данных.

Приложение Fix It хранит отправленные изображения как общедоступные. Это означает, что любой пользователь, который находит URL-адрес, может получить доступ к изображениям. Образы можно защитить, а не общедоступные.

Нет сценариев автоматизации PowerShell для очередей

Примеры скриптов автоматизации PowerShell были написаны только для базовой версии Fix It, которая полностью выполняется в Служба приложений Azure веб-приложения. Мы не предоставили скрипты для настройки и развертывания в веб-приложении, а также среду облачной службы, необходимую для обработки очередей.

Специальная обработка HTML-кодов во входных данных пользователем

ASP.NET автоматически предотвращает множество способов, которыми злоумышленники могут пытаться атаковать межсайтовые сценарии, вводя скрипты в текстовые поля ввода пользователем. А вспомогательное средство MVC DisplayFor , используемое для отображения заголовков задач и заметок, автоматически кодирует значения в ФОРМАТЕ HTML, отправляемые в браузер. Но в рабочем приложении может потребоваться принять дополнительные меры. Дополнительные сведения см. в разделе Запрос проверки в ASP.NET.

Рекомендации

Ниже приведены некоторые проблемы, которые были устранены после обнаружения при проверке кода и тестировании исходной версии приложения Fix It. Некоторые были вызваны тем, что исходный кодировщик не знал о конкретных рекомендациях, некоторые просто потому, что код был написан быстро и не был предназначен для выпущенного программного обеспечения. Мы перечисляем здесь проблемы на случай, если мы узнали из этого обзора и тестирования, что может быть полезно для других пользователей, которые также разрабатывают веб-приложения.

Удаление репозитория базы данных

Класс FixItTaskRepository должен удалить экземпляр Entity Framework DbContext . Мы сделали это, реализовав IDisposableFixItTaskRepository в классе :

public class FixItTaskRepository : IFixItTaskRepository, IDisposable
{
    private MyFixItContext db = new MyFixItContext();

    // other code not shown

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // Free managed resources.
            if (db != null)
            {
                db.Dispose();
                db = null;
            }
        }
    }
}

Обратите внимание, что AutoFac автоматически удаляет FixItTaskRepository экземпляр, поэтому нам не нужно явным образом удалять его.

Другой вариант — удалить DbContext переменную-член из FixItTaskRepository, а вместо этого создать локальную DbContext переменную в каждом методе репозитория в инструкции using . Пример:

// Alternate way to dispose the DbContext
using (var db = new MyFixItContext())
{
    fixItTask = await db.FixItTasks.FindAsync(id);
}

Регистрация одноэлементных экземпляров как таковых с помощью внедрения внедрения зависимостей

Так как требуется только один экземпляр PhotoService класса и Logger класса , эти классы должны быть зарегистрированы как отдельные экземпляры для внедрения зависимостей в DependenciesConfig.cs:

builder.RegisterType<Logger>().As<ILogger>().SingleInstance();
builder.RegisterType<FixItTaskRepository>().As<IFixItTaskRepository>();
builder.RegisterType<PhotoService>().As<IPhotoService>().SingleInstance();

Безопасность: не показывать сведения об ошибке пользователям

Исходное приложение "Исправить" не имеет универсальной страницы ошибок и просто позволяет всем исключениям отображаться в пользовательском интерфейсе, поэтому некоторые исключения, такие как ошибки подключения к базе данных, могут привести к отображению полной трассировки стека в браузере. Подробные сведения об ошибках иногда могут способствовать атакам злоумышленников. Решение заключается в регистрации сведений об исключении и отображении страницы ошибки для пользователя, которая не содержит сведения об ошибке. Приложение Fix It уже вело журнал, и для отображения страницы ошибки мы добавили <customErrors mode=On> в файл Web.config.

<system.web>
  <customErrors mode="On"/>
  <authentication mode="None" />
  <compilation debug="true" targetFramework="4.5" />
  <httpRuntime targetFramework="4.5" />
</system.web>

По умолчанию это приводит к отображению views \Shared\Error.cshtml для ошибок. Вы можете настроить Файл Error.cshtml или создать собственное представление страницы ошибок и добавить defaultRedirect атрибут. Вы также можете указать различные страницы ошибок для конкретных ошибок.

Безопасность: разрешить только редактирование задачи ее создателем

На странице Индекс панели мониторинга отображаются только задачи, созданные вошедшего в систему пользователя, но злоумышленник может создать URL-адрес с идентификатором для задачи другого пользователя. Мы добавили код в DashboardController.cs для возврата 404 в этом случае:

public async Task<ActionResult> Edit(int id)
{
    FixItTask fixittask = await fixItRepository.FindTaskByIdAsync(id);
    if (fixittask == null)
    {
        return HttpNotFound();
    }

    // Verify logged in user owns this FixIt task.
    if (User.Identity.Name != fixittask.Owner)
    {
       return HttpNotFound();
    }

    return View(fixittask);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(int id, [Bind(Include = "CreatedBy,Owner,Title,Notes,PhotoUrl,IsDone")]FormCollection form)
{
    FixItTask fixittask = await fixItRepository.FindTaskByIdAsync(id);

    // Verify logged in user owns this FixIt task.
    if (User.Identity.Name != fixittask.Owner)
    {
       return HttpNotFound();
    }

    if (TryUpdateModel(fixittask, form))
    {
        await fixItRepository.UpdateAsync(fixittask);
        return RedirectToAction("Index");
    }

    return View(fixittask);
}

Не глотать исключения

Исходное приложение Fix It только что вернуло значение NULL после ведения журнала исключения, которое было вызвано SQL-запросом:

catch (Exception e)
{
    log.Error(e, "Error in FixItTaskRepository.FindTasksByOwnerAsync(userName={0})", userName);
    return null;
}

Это позволит пользователю выглядеть так, как если бы запрос завершился успешно, но не вернул строк. Решение заключается в повторном вызове исключения после перехвата и ведения журнала:

catch (Exception e)
{
    log.Error(e, "Error in FixItTaskRepository.FindTasksByCreatorAsync(creater={0})", creator);
    throw;
}

Перехват всех исключений в рабочих ролях

Любые необработанных исключений в рабочей роли приведут к перезапуску виртуальной машины, поэтому вам нужно упаковать все действия в блок try-catch и обработать все исключения.

Указание длины строковых свойств в классах сущностей

Чтобы отобразить простой код, исходная версия приложения Fix It не указала длину полей сущности FixItTask, и в результате они были определены как varchar(max) в базе данных. В результате пользовательский интерфейс будет принимать практически любой объем входных данных. При указании длины задаются ограничения, которые применяются как к входным данным пользователя на веб-странице, так и к размеру столбца в базе данных:

public class FixItTask
{
    public int FixItTaskId  { get; set; }
    [StringLength(80)]
    public string CreatedBy { get; set; }
    [Required]
    [StringLength(80)]
    public string Owner { get; set; }
    [Required]
    [StringLength(80)]
    public string Title { get; set; }
    [StringLength(1000)]
    public string Notes { get; set; }
    [StringLength(200)]
    public string PhotoUrl { get; set; }
    public bool IsDone      { get; set; }  
}

Пометьте закрытые члены как доступные только для чтения, если они не должны изменяться

Например, в DashboardController классе создается экземпляр FixItTaskRepository класса , который не должен изменяться, поэтому мы определили его как только для чтения.

public class DashboardController : Controller
    {
        private readonly IFixItTaskRepository fixItRepository = null;

Использовать список. Any() вместо списка. Count() > 0

Если вас интересует только то, соответствует ли один или несколько элементов в списке указанным критериям, используйте метод Any , так как он возвращается, как только будет найден элемент, соответствующий условиям, в то время как Count методу всегда приходится выполнять итерацию по каждому элементу. Файл Index.cshtml панели мониторинга изначально имел следующий код:

@if (Model.Count() == 0) {
    <br />
    <div>You don't have anything currently assigned to you!!!</div>
}

Мы изменили его следующим образом:

@if (!Model.Any()) {
    <br />
    <div>You don't have anything currently assigned to you!!!</div>
}

Создание URL-адресов в представлениях MVC с помощью вспомогательных средств MVC

Для кнопки Создать исправление на домашней странице приложение Fix It жестко закодировали элемент привязки:

<a href="/Tasks/Create" class="btn btn-primary btn-large">Create a New FixIt &raquo;</a>

Для таких ссылок на просмотр и действие лучше использовать вспомогатель URL.Action HTML, например:

@Url.Action("Create","Tasks")

Использование Task.Delay вместо Thread.Sleep в рабочей роли

Шаблон нового проекта помещает Thread.Sleep в пример кода для рабочей роли, но если поток переходит в спящий режим, пул потоков создает дополнительные ненужные потоки. Избежать этого можно с помощью Task.Delay .

while (true)
{
    try
    {
        await queueManager.ProcessMessagesAsync();
    }
    catch (Exception ex)
    {
        logger.Error(ex, "Exception in worker role Run loop.");
    }
    await Task.Delay(1000);
}

Избегайте асинхронного void

Если асинхронный метод не должен возвращать значение, возвращается Task тип, а не void.

Этот пример из класса :FixItQueueManager

// Correct
public async Task SendMessageAsync(FixItTask fixIt) { ... }

// Incorrect
public async void SendMessageAsync(FixItTask fixIt) { ... }

Следует использовать async void только для обработчиков событий верхнего уровня. Если вы определяете метод как async void, вызывающий объект не может ожидать метод или перехватывать исключения, создаваемые методом. Дополнительные сведения см. в разделе Рекомендации по асинхронном программированию.

Использование маркера отмены для прерывания цикла рабочей роли

Как правило, метод Run для рабочей роли содержит бесконечный цикл. При остановке рабочей роли вызывается метод RoleEntryPoint.OnStop . Этот метод следует использовать для отмены работы, выполняемой внутри метода Run , и корректного завершения работы. В противном случае процесс может быть завершен в середине операции.

Отказ от автоматической процедуры mime sniffing

В некоторых случаях интернет-Обозреватель сообщает о типе MIME, отличном от типа, заданного веб-сервером. Например, если интернет-Обозреватель находит HTML-содержимое в файле, доставляемом с заголовком HTTP-ответа Content-Type: text/plain, интернет-Обозреватель определяет, что содержимое должно быть отрисовывается в формате HTML. К сожалению, это "mime-sniffing" также может привести к проблемам безопасности для серверов, на котором размещено недоверенное содержимое. Чтобы решить эту проблему, Internet Обозреватель 8 внесла ряд изменений в код определения типа MIME и позволяет разработчикам приложений отказаться от MIME-sniffing. Следующий код был добавлен в файлWeb.config .

<system.webServer>
     <httpProtocol>
        <customHeaders>
           <add name="X-Content-Type-Options" value="nosniff"/>
        </customHeaders>
     </httpProtocol>
     <modules>
      <remove name="FormsAuthenticationModule" />
    </modules>
  </system.webServer>

Включение объединения и минификации

Когда Visual Studio создает новый веб-проект, объединение и минификация файлов JavaScript не включены по умолчанию. Мы добавили строку кода в Файл BundleConfig.cs:

// For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
    bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                "~/Scripts/jquery-{version}.js"));
 
   // Code removed for brevity/
 
   BundleTable.EnableOptimizations = true;
}

Установка времени ожидания для файлов cookie проверки подлинности

По умолчанию срок действия файлов cookie проверки подлинности истекает через две недели. Более короткое время является более безопасным. Этот параметр можно изменить в файле StartupAuth.cs:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    LoginPath = new PathString("/Account/Login"),
    ExpireTimeSpan = System.TimeSpan.FromMinutes(20)
});

Запуск приложения из Visual Studio на локальном компьютере

Существует два способа запуска приложения Fix It.

  • Запустите базовое приложение, которое записывает новые задачи непосредственно в базу данных SQL.
  • Запустите приложение, используя очередь и серверную службу для создания задач. Шаблон очереди описан в разделе Шаблон работы, ориентированный на очередь.

Запуск базового приложения

  1. Установите Visual Studio 2017.
  2. Установите пакет Azure SDK для .NET для Visual Studio.
  3. Скачайте файл .zip из коллекции кода MSDN.
  4. В проводник щелкните правой кнопкой мыши файл .zip и выберите пункт Свойства, а затем в окно свойств выберите Разблокировать.
  5. Распакуйте файл.
  6. Дважды щелкните SLN-файл, чтобы запустить Visual Studio.
  7. В меню Сервис выберите диспетчер пакетов NuGet, а затем консоль диспетчера пакетов.
  8. В консоли диспетчера пакетов (PMC) щелкните Восстановить.
  9. Закройте Visual Studio.
  10. Запустите эмулятор службы хранилища Azure.
  11. Перезапустите Visual Studio, открыв файл решения, закрытый на предыдущем шаге.
  12. Убедитесь, что в качестве запускаемого проекта задан проект FixIt, а затем нажмите клавиши CTRL+F5, чтобы запустить проект.

Запуск приложения с обработкой очередей

  1. Следуйте инструкциям в разделе Запуск базового приложения, а затем закройте браузер и Visual Studio.

  2. Запустите Visual Studio с правами администратора. (Вы будете использовать эмулятор вычислений Azure, которому требуются права администратора.)

  3. В файле Web.config приложения в проекте MyFixIt (веб-проекте) измените значение appSettings/UseQueues на true:

    <appSettings>
        <!-- Other settings not shown -->
        <add key="UseQueues" value="true"/>
    </appSettings>
    
  4. Если эмулятор службы хранилища Azure еще не запущен, запустите его снова.

  5. Запустите веб-проект FixIt и проект MyFixItCloudService одновременно.

    Использование Visual Studio:

    1. Нажмите клавишу F5 , чтобы запустить проект FixIt.
    2. В Обозреватель решений щелкните правой кнопкой мыши проект MyFixItCloudService и выберите отладка>Запустить новый экземпляр.

    Использование Visual Studio 2013 Express для Интернета:

    1. В Обозреватель решений щелкните правой кнопкой мыши решение FixIt и выберите Свойства.

    2. Выберите Несколько запускаемых проектов.

    3. В раскрывающемся списке Действие в разделах MyFixIt и MyFixItCloudService выберите Пуск.

    4. Нажмите кнопку ОК.

    5. Нажмите клавишу F5, чтобы запустить оба проекта.

      При запуске проекта MyFixItCloudService Visual Studio запускает эмулятор вычислений Azure. В зависимости от конфигурации брандмауэра может потребоваться разрешить эмулятор через брандмауэр.

Развертывание базового приложения в Служба приложений Azure веб-приложения с помощью скриптов Windows PowerShell

Чтобы проиллюстрировать шаблон "Автоматизация всего ", приложение Fix It предоставляется со скриптами, которые настраивают среду в Azure и развертывают проект в новой среде. В следующих инструкциях объясняется, как использовать скрипты.

Если вы хотите выполнять в Azure без использования очередей и внесли изменения для локального запуска с очередями, убедитесь, что для параметра UseQueues appSetting задано значение false, прежде чем выполнять следующие инструкции.

В этих инструкциях предполагается, что вы уже скачали и запускали решение Fix It локально, а также что у вас есть учетная запись Azure или подписка Azure, которыми вы уполномочены управлять.

  1. Установите консоль Azure PowerShell. Инструкции см. в статье Приступая к работе с командлетами Azure PowerShell.

    Эта настраиваемая консоль настроена для работы с подпиской Azure. Модуль Azure устанавливается в каталог Program Files и автоматически импортируется при каждом использовании консоли Azure PowerShell.

    Если вы предпочитаете работать в другой хост-программе, например Windows PowerShell ISE, обязательно используйте командлет Import-Module для импорта модуля Azure или используйте команду в модуле Azure, чтобы активировать автоматический импорт модуля.

  2. Запустите Azure PowerShell с параметром Запуск от имени администратора.

  3. Выполните командлет Set-ExecutionPolicy, чтобы задать для политики выполнения Azure PowerShell значение RemoteSigned. Введите Y (да), чтобы завершить изменение политики.

    PS C:\> Set-ExecutionPolicy RemoteSigned
    

    Этот параметр позволяет запускать локальные скрипты без цифровой подписи. (Вы также можете задать для политики Unrestrictedвыполнения значение , что устранит необходимость в разблокировки позже, но это не рекомендуется из соображений безопасности.)

  4. Add-AzureAccount Выполните командлет , чтобы настроить PowerShell с учетными данными для вашей учетной записи.

    PS C:\> Add-AzureAccount
    

    Срок действия этих учетных данных истекает через некоторое время, и вам придется повторно запустить Add-AzureAccount командлет. По мере написания этой электронной книги ограничение времени до истечения срока действия учетных данных составляет 12 часов.

  5. Если у вас несколько подписок, используйте командлет Select-AzureSubscription, чтобы указать подписку, в которой вы хотите создать тестовую среду.

  6. Импортируйте сертификат управления для той же подписки Azure с помощью Get-AzurePublishSettingsFile командлетов и Import-AzurePublishSettingsFile . Первый из этих командлетов скачивает файл сертификата, а во втором вы указываете расположение этого файла для его импорта. > [! ВАЖНО]

    Сохраните скачанный файл в безопасном расположении или удалите его, когда закончите работу с ним, так как он содержит сертификат, который можно использовать для управления службами Azure.

    PS C:\Users\username\Documents\Visual Studio 2013\Projects\MyFixIt\Automation> Get-AzurePublishSettingsFile
    PS C:\Users\username\Documents\Visual Studio 2013\Projects\MyFixIt\Automation> Import-AzurePublishSettingsFile "C:\Users
    \username\Downloads\Azure MSDN - Visual Studio Ultimate-12-14-2013-credentials.publishsettings"
    

    Сертификат используется для вызова REST API, который обнаруживает IP-адрес компьютера разработки, чтобы задать правило брандмауэра на сервере База данных SQL.

  7. Выполните командлет Set-Location (псевдонимы — cd, chdirи sl), чтобы перейти в каталог, содержащий скрипты. (Они находятся в папке Службы автоматизации в папке решения Fix It.) Поместите путь в кавычки, если любое из имен каталогов содержит пробелы. Например, чтобы перейти в c:\Sample Apps\FixIt\Automation каталог, можно ввести следующую команду:

    PS C:\> cd "c:\Sample Apps\MyFixIt\Automation"
    
  8. Чтобы разрешить Windows PowerShell выполнять эти скрипты, используйте командлет Unblock-File. (Скрипты блокируются, так как они были загружены из Интернета.)

    Предупреждение

    Безопасность. Перед запуском Unblock-File в любом скрипте или исполняемом файле откройте файл в Блокноте, проверьте команды и убедитесь, что они не содержат вредоносного кода.

    Например, следующая команда выполняет Unblock-File командлет для всех скриптов в текущем каталоге.

    PS C:\Sample Apps\FixIt\Automation> Unblock-File -Path .\*.ps1
    
  9. Чтобы создать веб-приложение для базового приложения (без обработки очередей), выполните скрипт создания среды.

    Обязательный Name параметр указывает имя базы данных и также используется для учетной записи хранения, создаваемой скриптом. Имя должно быть глобально уникальным в пределах домена azurewebsites.net. Если указать имя, которое не является уникальным, например Fixit или Test (или даже как в примере, fixitdemo), New-AzureWebsite командлет завершится ошибкой с внутренней ошибкой, сообщающей о конфликте. Скрипт преобразует имя во все строчные буквы в соответствии с требованиями к именам для веб-приложений, учетных записей хранения и баз данных.

    Обязательный SqlDatabasePassword параметр указывает пароль для учетной записи администратора, которая будет создана для База данных SQL. Не включайте в пароль специальные XML-символы (& <> ;). Это ограничение способа написания скриптов, а не ограничение Azure.

    Например, если вы хотите создать веб-приложение с именем fixitdemo и использовать пароль администратора SQL Server Passw0rd1, можно ввести следующую команду:

    PS C:\Sample Apps\FixIt\Automation> .\New-AzureWebsiteEnv.ps1 -Name 
    fixitdemo <required params here>
    

    Имя должно быть уникальным в домене azurewebsites.net, а пароль должен соответствовать База данных SQL требованиям по сложности пароля. (Пример Passw0rd1 соответствует требованиям.)

    Обратите внимание, что команда начинается с ". Чтобы предотвратить вредоносное выполнение скриптов, Windows PowerShell требует указать полный путь к файлу скрипта при выполнении скрипта. Можно использовать точку, чтобы указать текущий каталог (".") или указать полный путь, например:

    PS C:\Temp\FixIt\Automation> C:\Temp\FixIt\Automation\New-AzureWebsiteEnv.ps1 -Name fixitdemo -SqlDatabasePassword Pas$w0rd
    

    Дополнительные сведения о скрипте см. в командлете Get-Help .

    PS C:\Sample Apps\FixIt\Automation> Get-Help -Full .\New-AzureWebsiteEnv.ps1
    

    Для фильтрации возвращаемой справки можно использовать Detailedпараметры , Full, Parametersи Examples командлета Get-Help.

    Если скрипт завершается сбоем или возникают ошибки, например "New-AzureWebsite: call Set-AzureSubscription and Select-AzureSubscription first", возможно, вы не завершили настройку Azure PowerShell.

    После завершения скрипта вы можете использовать портал управления Azure, чтобы просмотреть созданные ресурсы, как показано в разделе Автоматизация всего .

  10. Чтобы развернуть проект FixIt в новой среде Azure, используйте скрипт AzureWebsite.ps1 . Пример:

    PS C:\Sample Apps\FixIt\Automation> .\Publish-AzureWebsite.ps1 ..\MyFixIt\MyFixIt.csproj -Launch
    

    Когда развертывание будет завершено, откроется браузер с параметром Fix It запущен в Azure.

Устранение неполадок скриптов Windows PowerShell

Наиболее распространенные ошибки, возникающие при выполнении этих скриптов, связаны с разрешениями. Убедитесь, что Add-AzureAccount и Import-AzurePublishSettingsFile выполнены успешно, и что вы использовали их для одной подписки Azure. Даже в случае Add-AzureAccount успеха, возможно, придется запустить его снова. Срок действия добавленных Add-AzureAccount разрешений истекает через 12 часов.

Ссылка на объект не указывает на экземпляр объекта.

Если скрипт возвращает ошибки, такие как "Ссылка на объект не задана для экземпляра объекта", то есть Windows PowerShell не может найти объект для обработки (это исключение пустой ссылки), выполните Add-AzureAccount командлет и повторите попытку скрипта.

New-AzureSqlDatabaseServer : Object reference not set to an instance of an object.
At C:\ps-test\azure-powershell-samples-master\WebSite\create-azure-sql.ps1:80 char:19
+ $databaseServer = New-AzureSqlDatabaseServer -AdministratorLogin $UserName -Admi ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [New-AzureSqlDatabaseServer], NullReferenceException
    + FullyQualifiedErrorId : 
Microsoft.WindowsAzure.Commands.SqlDatabase.Server.Cmdlet.NewAzureSqlDatabaseServer

InternalError: сервер столкнулся с внутренней ошибкой.

Командлет New-AzureWebsite возвращает внутреннюю ошибку, если имя не является уникальным в домене azurewebsites.net. Чтобы устранить эту ошибку, используйте другое значение для имени, которое находится в параметре Name New-AzureWebsiteEnv.ps1.

New-AzureWebsite : InternalError: The server encountered an internal error. 
Please retry the request.
At line:1 char:1
+ New-AzureWebsite -Name fixitdemo
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          
: CloseError: (:) [New-AzureWebsite], Exception
+ FullyQualifiedErrorId : 
Microsoft.WindowsAzure.Commands.Websites.NewAzureWebsiteCommand

Перезапуск скрипта

Если необходимо перезапустить скрипт New-AzureWebsiteEnv.ps1 из-за сбоя до вывода сообщения "Скрипт завершен", может потребоваться удалить ресурсы, созданные скриптом до его остановки. Например, если скрипт уже создал веб-приложение ContosoFixItDemo и вы снова запустите сценарий с тем же именем, сценарий завершится ошибкой, так как используется имя.

Чтобы определить, какие ресурсы скрипт создал до остановки, используйте следующие командлеты:

  • Get-AzureWebsite
  • Get-AzureSqlDatabaseServer
  • Get-AzureSqlDatabase: чтобы выполнить этот командлет, передайте имя сервера базы данных в Get-AzureSqlDatabase: Get-AzureSqlDatabaseServer | Get-AzureSqlDatabase.

Чтобы удалить эти ресурсы, используйте следующие команды. Обратите внимание, что при удалении сервера базы данных автоматически удаляются базы данных, связанные с сервером.

  • Get-AzureWebsite -Name <WebsiteName> | Remove-AzureWebsite
  • Get-AzureSqlDatabase -Name <DatabaseName> -ServerName <DatabaseServerName> | Remove-SqlAzureDatabase
  • Get-AzureSqlDatabaseServer | Remove-AzureSqlDatabaseServer

Развертывание приложения с обработкой очередей в Служба приложений Azure веб-приложения и облачной службе Azure

Чтобы включить очереди, внесите следующее изменение в файл MyFixIt\Web.config. В appSettingsразделе измените значение UseQueues на true:

<appSettings>
    <!-- Other settings not shown -->
    <add key="UseQueues" value="true"/>
</appSettings>

Затем разверните приложение MVC в веб-приложении в Служба приложений Azure, как описано ранее.

Затем создайте облачную службу Azure. Скрипты, входящие в состав приложения Fix It, не создают и не развертывают облачную службу, поэтому для этого необходимо использовать портал Azure. На портале щелкните Создать -- вычислениебыстрое созданиеоблачной службы -- , а затем введите URL-адрес и расположение центра обработки данных. Используйте тот же центр обработки данных, в котором развернуто веб-приложение.

Схема портала облачной службы Azure и нескольких вкладок с доступными вариантами для создания проекта облачной службы Azure

Перед развертыванием облачной службы необходимо обновить некоторые файлы конфигурации.

В MyFixIt.WorkerRole\app.config в разделе connectionStringsзамените appdb значение строка подключения фактическим строка подключения для База данных SQL. Вы можете получить строка подключения на портале. На портале щелкните Базы данных - SQLappdb - Просмотр База данных SQL строк подключения для ADO .Net, ODBC, PHP и JDBC. Скопируйте ADO.NET строка подключения и вставьте значение в файл app.config. Замените "{your_password_here}" паролем базы данных. (Предполагается, что вы использовали скрипты для развертывания приложения MVC, вы указали пароль базы данных в параметре скрипта SqlDatabasePassword .)

Результат должен выглядеть следующим образом:

<add name="appdb" connectionString="Server=tcp:####.database.windows.net,1433;Database=appdb;User ID=####;Password=####;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;" providerName="System.Data.SqlClient" />

В том же MyFixIt.WorkerRole\app.config файле в разделе appSettingsзамените два значения заполнителей для учетной записи хранения Azure.

<appSettings>
  <add key="StorageAccountName" value="{StorageAccountName}" />
  <add key="StorageAccountAccessKey" value="{StorageAccountAccessKey}" />
</appSettings>

Ключ доступа можно получить на портале. См . статью Управление учетными записями хранения.

В MyFixItCloudService\ServiceConfiguration.Cloud.cscfg замените те же два значения заполнителей для учетной записи хранения Azure.

<ConfigurationSettings>
    <Setting name="Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" 
             value="DefaultEndpointsProtocol=https;AccountName={StorageAccountName};AccountKey={StorageAccountAccessKey}" />
  </ConfigurationSettings>

Теперь вы готовы к развертыванию облачной службы. В разделе Изучение решений щелкните правой кнопкой мыши проект MyFixItCloudService и выберите Опубликовать. Дополнительные сведения см. в разделе Развертывание приложения в Azure, который находится в части 2 этого руководства.