Introdução aos Serviços de Nuvem do Azure (clássico) e ao ASP.NET
Visão geral
Importante
Os Serviços de Nuvem (clássicos) estão obsoletos para todos os clientes desde 1º de setembro de 2024. Todas as implantações em execução existentes serão interrompidas e encerradas pela Microsoft e os dados serão perdidos permanentemente a partir de outubro de 2024. As novas implantações devem usar o novo modelo de implantação baseado no Azure Resource Manager Serviços de Nuvem do Azure (suporte estendido) .
Esse tutorial mostra como criar um aplicativo .NET de várias camadas com um front-end do ASP.NET MVC (Model-View-Controller) e como implantá-lo em um Serviço de nuvem do Azure. O aplicativo usa o Banco de Dados SQL do Azure, o serviço Blob do Azure e o serviço Fila do Azure. Você poderá baixar o projeto do Visual Studio na Galeria de Códigos do MSDN (Microsoft Developer Network).
O tutorial mostra como criar e executar o aplicativo localmente, como implantá-lo no Azure e executá-lo na nuvem e como criá-lo do zero. Você pode começar criando do zero e depois fazer o teste e implantar as etapas posteriormente se preferir.
O aplicativo Contoso Ads
O aplicativo é um painel de anúncios eletrônico. Os usuários criam um anúncio inserindo texto e carregando uma imagem. Eles podem ver uma lista de anúncios com imagens em miniatura e podem ver a imagem em tamanho total ao selecionar um anúncio para ver os detalhes.
O aplicativo usa o padrão centrado em fila para descarregar o trabalho intensivo de CPU de criação de miniaturas para um processo de back-end.
Arquitetura alternativa: Serviço de Aplicativo e WebJobs
Este tutorial mostra como executar front-end e back-end no serviço de nuvem do Azure. Uma alternativa é executar o front-end no Serviço de Aplicativo do Azure e usar o recurso WebJobs para o back-end. Para obter um tutorial que usa WebJobs, consulte Introdução ao SDK WebJobs do Azure. Para obter informações sobre como escolher os serviços que melhor se ajustam ao seu cenário, confira Comparação entre o Serviço de Aplicativo do Azure, Serviços de Nuvem e máquinas virtuais.
Metas de aprendizado
- Como habilitar seu computador para desenvolvimento do Azure ao instalar o SDK do Azure.
- Como criar um projeto de serviço de nuvem do Visual Studio com uma função de trabalho e uma função Web MVC do ASP.NET.
- Como testar o projeto de serviço de nuvem localmente usando o Emulador de Armazenamento do Azure.
- Como publicar o projeto de nuvem em um serviço de nuvem do Azure e testar usando uma conta de armazenamento do Azure.
- Como carregar arquivos e armazená-los no serviço Blob do Azure.
- Como usar o serviço Fila do Azure para comunicação entre camadas.
Pré-requisitos
O tutorial assume que você conhece os conceitos básicos sobre os serviços de nuvem do Azure como terminologia de função web e de função de trabalho. Também assumimos que você sabe como trabalhar com projetos ASP.NET MVC ou de Web Forms no Visual Studio. O aplicativo função Web usa MVC, mas a maior parte do tutorial também aplica-se a Formulários da Web.
Você pode executar o aplicativo localmente sem uma assinatura do Azure, mas precisa de uma para implantar o aplicativo na nuvem. Se não tem uma conta, você pode ativar os benefícios de assinante MSDN ou inscrever-se em uma avaliação gratuita.
As instruções do tutorial funcionam com qualquer um dos seguintes produtos:
- Visual Studio 2013
- Visual Studio 2015
- Visual Studio 2017
- Visual Studio 2019
Se você não tiver nenhum desses produtos, o Visual Studio poderá ser instalado automaticamente ao instalar o SDK do Azure.
Arquitetura do aplicativo
O aplicativo armazena anúncios em um banco de dados SQL, usando o Entity Framework Code First para criar tabelas e acessar dados. Para cada anúncio, o banco de dados armazena duas URLs: uma para a imagem em tamanho total e outra para a miniatura.
Quando um usuário carrega uma imagem, o front-end sendo executado em uma função Web armazena a imagem em um Blob do Azuree armazena as informações do anúncio no banco de dados com uma URL que aponta para o blob. Ao mesmo tempo, ele grava uma mensagem em uma fila do Azure. Um processo de back-end sendo executado periodicamente em um função de trabalho consulta a fila para ver se há novas mensagens. Quando uma mensagem é exibida, a função de trabalho cria uma miniatura para essa imagem e atualiza o campo do banco de dados da URL de miniatura desse anúncio. O diagrama a seguir mostra como as partes do aplicativo interagem.
Configurar o ambiente de desenvolvimento
Para começar, configure seu ambiente de desenvolvimento com o Visual Studio e o SDK do Azure.
O Visual Studio 2019 inclui o SDK do Azure. Se você estiver usando o Visual Studio 2019, nenhuma configuração adicional é necessária para o ambiente de desenvolvimento.
Para o Visual Studio 2015, clique no seguinte link para instalar o SDK do Azure para Visual Studio 2015.
Para o Visual Studio 2013, clique no seguinte link para instalar o SDK do Azure para Visual Studio 2013.
Se você não tiver o Visual Studio instalado, use o seguinte para instalar o Visual Studio 2019 com o SDK do Azure.
Observação
Dependendo de quantas dependências de SDK você já tiver no seu computador, a instalação do SDK pode demorar bastante, de vários minutos a meia hora ou mais.
Baixar e executar a solução completa
Baixar e descompactar a solução concluída.
Inicie o Visual Studio.
No menu Arquivo, escolha Abrir Projeto, navegue até onde você baixou a solução e, em seguida, abra o arquivo de solução.
Para criar a solução, pressione CTRL+SHIFT+B.
Por padrão, o Visual Studio restaura automaticamente o conteúdo do pacote NuGet, que não foi incluído no arquivo .zip. Se os pacotes não forem restaurados, instale-os manualmente acessando a caixa de diálogo Gerenciar Pacotes NuGet para Solução e clicando no botão Restaurar na parte superior direita.
No Gerenciador de Soluções, certifique-se de que ContosoAdsCloudService foi selecionado como o projeto de inicialização.
Se você estiver usando o Visual Studio 2015 ou superior, altere a cadeia de conexão do SQL Server no arquivo Web.config do aplicativo do projeto ContosoAdsWeb e no arquivo ServiceConfiguration.Local.cscfg do projeto ContosoAdsCloudService. Em cada caso, altere "(localdb)\v11.0" para "(localdb)\MSSQLLocalDB".
Para executar o aplicativo, pressione CTRL+F5.
Quando você executar um projeto de serviço de nuvem localmente, o Visual Studio invocará automaticamente o emulador de computação e o emulador de armazenamento do Azure. O emulador de computação usa os recursos do seu computador para simular os ambientes de função Web e de função de trabalho. O emulador de armazenamento usa um banco de dados LocalDB do SQL Server Express para simular o armazenamento em nuvem do Azure.
Na primeira vez em que você executar um projeto de serviço de nuvem, levará por volta de um minuto para que os emuladores sejam inicializados. Quando a inicialização do emulador for finalizada, o navegador padrão abrirá na home page do aplicativo.
Selecione Criar um anúncio.
Insira alguns dados de teste e selecione uma imagem .jpg a ser carregada e selecione Criar.
O aplicativo vai para a página do Índice, mas não mostra uma miniatura para o novo anúncio porque esse processamento ainda não aconteceu.
Aguarde um momento e depois atualize a Página de índice para ver a miniatura.
Selecione Detalhes do anúncio para exibir a imagem em tamanho real.
Você está executando o aplicativo totalmente em seu computador local sem conexão com a nuvem. O emulador de armazenamento guarda os dados de fila e do Blob em um banco de dados LocalDB do SQL Server Express e o aplicativo armazena os dados do anúncio em outro banco de dados LocalDB. O Entity Framework Code First criou automaticamente o banco de dados de anúncio na primeira vez que o aplicativo Web tentou acessá-lo.
Na seção a seguir, você configura a solução para usar recursos de nuvem do Azure para filas, blobs e o banco de dados do aplicativo quando estiver em execução na nuvem. Se você preferisse continuar a executar localmente, porém usando os recursos de armazenamento e banco de dados de nuvem, isso seria possível. É apenas uma questão de configurar as cadeias de conexão, o que você verá como fazer.
Implantar o aplicativo no Azure
Você executa as etapas a seguir para executar o aplicativo na nuvem:
- Criar um serviço de nuvem do Azure.
- Crie um banco de dados no Banco de Dados SQL do Azure.
- Crie uma conta de armazenamento do Azure.
- Configure a solução para usar seu banco de dados quando for executada no Azure.
- Configurar a solução para usar sua conta de armazenamento do Azure quando ela for executada no Azure.
- Implantar o projeto em seu serviço de nuvem do Azure.
Criar um serviço de nuvem do Azure
Um serviço de nuvem do Azure é o ambiente em que o aplicativo é executado.
No seu navegador, abra o portal do Azure.
Selecione Criar um recurso> Computação > Serviço de Nuvem.
Na caixa de entrada do DNS (Sistema de Nomes de Domínio), insira um prefixo de URL para o serviço de nuvem.
Essa URL precisa ser exclusiva. Você receberá uma mensagem de erro se o prefixo escolhido já estiver em uso.
Especifique um novo grupo de recursos para o serviço. Selecione Criar novo e digite um nome na caixa de entrada Grupo de recursos, como CS_contososadsRG.
Selecione a região onde deseja implantar o aplicativo.
Esse campo especifica em qual datacenter seu serviço de nuvem está hospedado. Para um aplicativo de produção, você escolheria a região mais próxima aos seus clientes. Para este tutorial, escolha a região mais próxima de você.
Selecione Criar.
Na imagem a seguir, um serviço de nuvem é criado com a URL CSvccontosoads.cloudapp.net.
Criar um banco de dados no Banco de Dados SQL do Azure
Quando o aplicativo é executado na nuvem, ele usa um banco de dados baseado em nuvem.
No portal do Azure, selecione Criar um recurso > Bancos de Dados > Banco de Dados SQL.
Na caixa Nome do Banco de Dados , insira contosoads.
No Grupo de recursos, escolha Usar existente e selecione o grupo de recursos usado para o serviço de nuvem.
Na imagem a seguir, selecione Servidor – Definir as configurações necessárias e Criar um novo servidor.
Se a assinatura já tiver um servidor, você poderá selecioná-lo da lista suspensa.
Em Nome do servidor , digite csvccontosodbserver.
Insira um Nome de Logon e Senha de administrador.
Se você selecionou Criar um novo servidor, não digitará um nome e senha existentes aqui. Você digitará um novo nome e senha que você está definindo agora para usar mais tarde ao acessar o banco de dados. Se você selecionou um servidor criado anteriormente, o portal solicitará a senha da conta de usuário administrativo que você já criou.
Selecione o mesmo Local que você escolheu para o serviço de nuvem.
Quando o serviço de nuvem e o banco de dados estão em datacenters diferentes (regiões diferentes), a latência aumenta e você incorre em cobranças pela largura de banda fora do data center. A largura de banda em um data center é gratuita.
Marque a opção Permitir que os serviços do Azure acessem o servidor.
Escolha Selecionar para o novo servidor.
Escolha Criar.
Criar uma conta de armazenamento do Azure
Uma conta de armazenamento do Azure fornece os recursos para dados de blob e fila de armazenamento na nuvem.
Em um aplicativo do mundo real, geralmente você cria contas separadas para dados de aplicativos e dados de log, e contas separadas para dados de teste e dados de produção. Para este tutorial, você usará apenas uma conta.
No portal do Azure, selecione Criar um recurso > Armazenamento > Conta de armazenamento – blob, arquivo, tabela, fila.
Na caixa da Nome , insira um prefixo de URL.
Esse prefixo juntamente com o texto que você vê abaixo da caixa é o URL exclusivo da sua conta de armazenamento. Se o prefixo inserido já estiver em uso por outra pessoa, escolha um prefixo diferente.
Defina o Modelo de implantação como Clássico.
Defina a lista suspensa Replicação para Armazenamento com redundância local.
Quando a replicação geográfica está habilitada para uma conta de armazenamento, o conteúdo armazenado é replicado para um datacenter secundário para habilitar o failover caso ocorra um grande desastre no local principal. A replicação geográfica pode incorrer em custos adicionais. Para contas de teste e desenvolvimento, geralmente, você não deseja pagar pela replicação geográfica. Para saber mais, confira Criar, gerenciar ou excluir uma conta de armazenamento.
No Grupo de recursos, selecione Usar existente e selecione o grupo de recursos usado para o serviço de nuvem.
Defina a lista suspensa Local como a mesma região escolhida para o serviço de nuvem.
Quando o serviço de nuvem e a conta de armazenamento estão em datacenters diferentes (regiões diferentes), a latência aumenta e você incorre em cobranças pela largura de banda fora do data center. A largura de banda em um data center é gratuita.
O grupos de afinidade do Azure fornecem um mecanismo para minimizar a distância entre os recursos em um data center, o que pode reduzir a latência. Esse tutorial não usa grupos de afinidade. Para obter mais informações, consulte Como criar um grupo de afinidade no Azure.
Escolha Criar.
Na imagem, uma conta de armazenamento é criada com a URL
csvccontosoads.core.windows.net
.
Configurar a solução para usar seu banco de dados no Banco de Dados SQL do Azure quando ele for executado no Azure
O projeto Web e o projeto de função de trabalho têm as próprias cadeias de conexão de banco de dados, e cada uma precisa apontar para o banco de dados no Banco de Dados SQL do Azure quando o aplicativo é executado no Azure.
Você usa uma transformação Web.config para a função Web e uma configuração de ambiente de serviço de nuvem para o trabalho.
Observação
Nesta seção e na próxima, você armazenará credenciais nos arquivos de projeto. Não armazene dados confidenciais em repositórios de código-fonte público.
No projeto ContosoAdsWeb, abra o arquivo de transformação Web.Release.config para o arquivo Web.config do aplicativo, exclua o bloco de comentário que contém um elemento
<connectionStrings>
e cole o código a seguir no lugar.<connectionStrings> <add name="ContosoAdsContext" connectionString="{connectionstring}" providerName="System.Data.SqlClient" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/> </connectionStrings>
Deixe o arquivo aberto para edição.
No portal do Azure, escolha Bancos de Dados SQL no painel esquerdo, selecione o banco de dados que você criou para este tutorial e selecione Mostrar cadeias de conexão.
O portal exibe as cadeias de conexão com um espaço reservado para a senha.
No arquivo de transformação Web.Release.config, exclua
{connectionstring}
e cole, em seu lugar, a cadeia de conexão ADO.NET do portal do Azure.Na cadeia de conexão que você colou no arquivo de transformação Web.Release.config, substitua
{your_password_here}
pela senha que você criou para o novo Banco de Dados SQL.Salve o arquivo.
Selecione e copie a cadeia de conexão (sem as aspas) para usar nas etapas a seguir para configurar o projeto de função de trabalho.
No Gerenciador de Soluções, em Funções no projeto de serviço de nuvem, clique com o botão direito do mouse em ContosoAdsWorker e escolha Propriedades.
Escolha a guia Configurações .
Altere Configuração de Serviço para Nuvem.
Selecione o campo Valor para a configuração
ContosoAdsDbConnectionString
e cole a cadeia de conexão que você copiou da seção anterior do tutorial.Salve suas alterações.
Configurar a solução para usar sua conta de armazenamento do Azure quando ela for executada no Azure
As cadeias de conexão da conta de armazenamento do Azure do projeto de função de trabalho e do projeto de função Web são armazenadas nas configurações de ambiente do projeto de serviço de nuvem. Para cada projeto, há um conjunto separado de configurações a serem usadas quando o aplicativo é executado localmente e quando é executado na nuvem. Você atualiza as configurações do ambiente de nuvem para projetos de trabalho e da Web.
No Gerenciador de soluções, clique com o botão direito em ContosoAdsWeb em Funções no projeto ContosoAdsCloudService e, em seguida, selecione Propriedades.
Escolha a guia Configurações . Na caixa suspensa Configuração de Serviço selecione Nuvem.
Selecione a entrada StorageConnectionString e você verá um botão de reticências (...) na extremidade direita da linha. Escolha o botão de reticências para abrir a caixa de diálogo Criar Cadeia de Conexão de Armazenamento.
Na caixa de diálogo Criar Cadeia de Conexão de Armazenamento, selecione Sua assinatura, escolha a conta de armazenamento que você criou anteriormente e selecione OK. O explorador solicitará as credenciais da sua conta do Azure se você ainda precisar entrar.
Salve suas alterações.
Siga o mesmo procedimento que usou para a cadeia de conexão
StorageConnectionString
para definir a cadeia de conexãoMicrosoft.WindowsAzure.Plugins.Diagnostics.ConnectionString
.Essa cadeia de conexão é usada para o log.
Siga o mesmo procedimento que usou para a função ContosoAdsWeb definir as duas cadeias de conexão da função ContosoAdsWorker. Não se esqueça de definir Configuração de Serviço como Nuvem.
As configurações de ambiente de função que você definiu usando a interface do usuário do Visual Studio são armazenadas nos seguintes arquivos do projeto ContosoAdsCloudService:
- ServiceDefinition.csdef - Define os nomes de configuração.
- ServiceConfiguration.Cloud.cscfg - Fornece os valores para quando o aplicativo for executado na nuvem.
- ServiceConfiguration.Local.cscfg - Fornece os valores para quando o aplicativo for executado localmente.
Por exemplo, ServiceDefinition.csdef inclui as seguintes definições:
<ConfigurationSettings>
<Setting name="StorageConnectionString" />
<Setting name="ContosoAdsDbConnectionString" />
</ConfigurationSettings>
E o arquivo ServiceConfiguration.Cloud.cscfg inclui os valores inseridos para essas configurações no Visual Studio.
<Role name="ContosoAdsWorker">
<Instances count="1" />
<ConfigurationSettings>
<Setting name="StorageConnectionString" value="{yourconnectionstring}" />
<Setting name="ContosoAdsDbConnectionString" value="{yourconnectionstring}" />
<!-- other settings not shown -->
</ConfigurationSettings>
<!-- other settings not shown -->
</Role>
A configuração <Instances>
especifica o número de máquinas virtuais nas quais o Azure executa o código de função do trabalho. A seção Próximas etapas inclui links para mais informações sobre a expansão de um serviço de nuvem.
Implantar o projeto no Azure
No Gerenciador de Soluções, clique com o botão direito do mouse no projeto de nuvem ContosoAdsCloudService e então selecione Publicar.
Na etapa Entrar do assistente Publicar aplicativo do Azure, selecione Avançar.
Na etapa Configurações do assistente, selecione Avançar.
As configurações padrão na guia Avançado são adequadas para este tutorial. Para obter mais informações sobre a guia avançada, consulte Assistente de publicação de aplicativo do Azure.
Na etapa Resumo, selecione Publicar.
A janela Log de atividade do Azure será exibida no Visual Studio.
Escolha o ícone de seta para a direita para expandir os detalhes da implantação.
A implantação pode levar cerca de 5 minutos ou mais para ser concluída.
Quando o status da implantação for concluído, selecione o URL do aplicativo Web para iniciar o aplicativo.
Você pode testar o aplicativo criando, visualizando e editando alguns anúncios, como fez ao executar o aplicativo localmente.
Observação
Ao finalizar o teste, exclua ou interrompa o serviço de nuvem. Mesmo que não estiver usando o serviço de nuvem, seus acúmulos serão cobrados porque os recursos do computador virtual serão reservados para o serviço. E se você deixá-lo em execução, qualquer um que encontrar sua URL poderá criar e exibir anúncios. No portal do Azure acesse a guia Visão Geral do seu serviço de nuvem e clique no botão Excluir na parte superior da página. Se apenas deseja evitar que outros acessem temporariamente o site, em vez disso clique em Parar . Nesse caso, as tarifas continuarão a acumular. Você pode seguir um procedimento semelhante para excluir o banco de dados SQL e a conta de armazenamento quando não precisar mais dela.
Criar o aplicativo do zero
Se você ainda precisar baixar o aplicativo completo, faça isso agora. Copie os arquivos do projeto baixado para o novo projeto.
A criação do Contoso Ads envolve as seguintes etapas:
- Criar um serviço de nuvem na solução Visual Studio.
- Atualizar e adicionar pacotes NuGet.
- Definir referências de projeto.
- Configurar cadeias de conexão.
- Adicionar arquivos de código.
Após a solução ser criada, você revisará o código exclusivo dos projetos de serviço de nuvem e dos blobs e filas do Azure.
Criar um serviço de nuvem na solução Visual Studio
No Visual Studio, selecione Novo Projeto from the Arquivo .
No painel esquerdo da caixa de diálogo Novo Projeto, expanda Visual C# e selecione os modelos de Nuvem; em seguida, selecione o modelo de Serviço de Nuvem do Azure.
Nomeie o projeto e a solução ContosoAdsCloudService e selecione OK.
Na caixa de diálogo Novo Projeto de Serviço de Nuvem , adicione uma função de trabalho e uma função web. Nomeie a função Web ContosoAdsWeb e a função de trabalho ContosoAdsWorker. (Use o ícone da caneta no painel direito para alterar os nomes padrão das funções.)
Ao ver a caixa de diálogo Novo projeto ASP.NET para a função Web, escolha o modelo MVC e selecione Alterar Autenticação.
Na caixa de diálogo Alterar Autenticação, escolha Sem Autenticação e selecione OK.
Na caixa de diálogo Novo projeto ASP.NET, selecione OK.
No Gerenciador de Soluções, clique com o botão direito do mouse na solução (não aquela de projetos) e selecione Adicionar – Novo Projeto.
Na caixa de diálogo Adicionar Novo Projeto, escolha Windows em Visual C# no painel esquerdo e selecione o modelo Biblioteca de Classes.
Nomeie o projeto ContosoAdsCommon e, em seguida, selecione OK.
Você precisa usar como referência o contexto e o modelo de dados do Entity Framework para os projetos de função de trabalho e da Web. Como alternativa, você pode definir as classes relacionadas ao EF no projeto de função Web e usar esse projeto como referência para o projeto de função de trabalho. Na abordagem alternativa, no entanto, o seu projeto de função de trabalho teria uma referência para assemblies da Web dos quais não precisa.
Atualizar e adicionar pacotes NuGet
Abra a caixa de diálogo Gerenciar Pacotes NuGet para a solução.
Na parte superior da janela, selecione Atualizações.
Procure o pacote WindowsAzure.Storage e, se estiver na lista, selecione-o e selecione os projetos Web e de trabalho para atualizá-lo e, em seguida, selecione Atualizar.
A biblioteca de clientes de armazenamento é atualizada com mais frequência do que os modelos de projeto do Visual Studio, portanto, você pode descobrir que a versão em um projeto recém-criado precisa ser atualizada.
Na parte superior da janela, selecione Procurar.
Encontre o pacote NuGet do EntityFramework e instale-o em todos os três projetos.
Encontre o pacote NuGet Microsoft.WindowsAzure.ConfigurationManager e instale-o no projeto de função de trabalho.
Definir referências de projeto
No projeto ContosoAdsWeb, defina uma referência para o projeto ContosoAdsCommon. Clique com o botão direito do mouse no projeto ContosoAdsWeb e, em seguida, selecione Referências - Adicionar Referências. Na caixa de diálogo Gerenciador de Referências, selecione Solução – Projetos no painel esquerdo e, em seguida, escolha ContosoAdsCommon e selecione OK.
No projeto ContosoAdsWorker, defina uma referência ao projeto ContosoAdsCommon.
ContosoAdsCommon contém o modelo de dados e a classe de contexto do Entity Framework, que usa o front-end e o back-end.
No projeto ContosoAdsWorker, defina uma referência para
System.Drawing
.Este assembly é usado pelo back-end para converter imagens em miniaturas.
Configurar cadeias de conexão
Nesta seção iremos configurar o Armazenamento do Azure e as cadeias de conexão do SQL para o teste local. As instruções de implantação fornecidas anteriormente no tutorial explicam como definir as cadeias de conexão para quando o aplicativo for executado na nuvem.
No projeto ContosoAdsWeb, abra o arquivo Web.config do aplicativo e insira o elemento
connectionStrings
a seguir após o elementoconfigSections
.<connectionStrings> <add name="ContosoAdsContext" connectionString="Data Source=(localdb)\v11.0; Initial Catalog=ContosoAds; Integrated Security=True; MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" /> </connectionStrings>
Se você estiver usando o Visual Studio 2015 ou superior, substitua "v11.0" por "MSSQLLocalDB".
Salve suas alterações.
No projeto ContosoAdsCloudService, clique com o botão direito do mouse em ContosoAdsWeb em Funções e, em seguida, selecione Propriedades.
Na janela Propriedades ContosoAdsWeb [Função], selecione a guia Configurações e, em seguida, selecione Adicionar Configuração.
Deixe Configuração de Serviço definida como Todas as configurações.
Adicione uma configuração chamada StorageConnectionString. Defina Tipo como ConnectionString e defina Valor como UseDevelopmentStorage=true.
Salve suas alterações.
Siga o mesmo procedimento para adicionar uma cadeia de conexão nas propriedades da função ContosoAdsWorker.
Enquanto ainda estiver na janela Propriedades ContosoAdsWorker [Função], adicione outra cadeia de conexão:
Nome: ContosoAdsDbConnectionString
Tipo: String
Valor: cole a mesma cadeia de conexão usada para o projeto de função Web. (O exemplo a seguir refere-se ao Visual Studio 2013. Não se esqueça de alterar a fonte de dados se copiar este exemplo e estiver usando o Visual Studio 2015 ou superior.)
Data Source=(localdb)\v11.0; Initial Catalog=ContosoAds; Integrated Security=True; MultipleActiveResultSets=True;
Adicionar arquivos de código
Nesta seção, você copiará códigos da solução baixada para a nova solução. As seções a seguir mostram e explicam as principais partes desse código.
Para adicionar arquivos a um projeto ou pasta, clique com o botão direito no projeto ou pasta e selecione Adicionar - Item existente. Selecione os arquivos desejados e, em seguida, selecione Adicionar. Se for perguntado se deseja substituir os arquivos existentes, selecione Sim.
No projeto ContosoAdsCommon, exclua o arquivo Class1.cs e substitua-o pelos arquivos Ad.cs e ContosoAdscontext.cs do projeto baixado.
No projeto ContosoAdsWeb, adicione os seguintes arquivos do projeto baixado.
- Global.asax.cs
- Na pasta Views\Shared: Layout.cshtml.
- Na pasta Views\Home: Index.cshtml.
- Na pasta Controllers: AdController.cs.
- Na pasta Views\Ad (crie a pasta primeiro): cinco arquivos .cshtml.
No projeto ContosoAdsWorker, adicione WorkerRole.cs do projeto baixado.
Agora você pode compilar e executar o aplicativo, conforme instruído anteriormente no tutorial, e o aplicativo usa recursos do emulador de armazenamento e do banco de dados local.
As seções a seguir explicam o código relacionado ao trabalho com os blobs e filas do ambiente do Azure. Este tutorial não explica como criar controladores e exibições do MVC usando scaffolding, como escrever código do Entity Framework que funciona com os bancos de dados do SQL Server ou os conceitos básicos de programação assíncrona no ASP.NET 4.5. Para obter informações sobre esses tópicos, consulte os seguintes recursos:
ContosoAdsCommon - Ad.cs
O arquivo Ad.cs file define uma enumeração para categorias de anúncios e uma classe de entidade POCO para as informações de anúncios.
public enum Category
{
Cars,
[Display(Name="Real Estate")]
RealEstate,
[Display(Name = "Free Stuff")]
FreeStuff
}
public class Ad
{
public int AdId { get; set; }
[StringLength(100)]
public string Title { get; set; }
public int Price { get; set; }
[StringLength(1000)]
[DataType(DataType.MultilineText)]
public string Description { get; set; }
[StringLength(1000)]
[DisplayName("Full-size Image")]
public string ImageURL { get; set; }
[StringLength(1000)]
[DisplayName("Thumbnail")]
public string ThumbnailURL { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime PostedDate { get; set; }
public Category? Category { get; set; }
[StringLength(12)]
public string Phone { get; set; }
}
ContosoAdsCommon - ContosoAdsContext.cs
A classe ContosoAdsContext especifica que a classe Ad é usada em uma coleção DbSet, que o Entity Framework armazena em um banco de dados SQL.
public class ContosoAdsContext : DbContext
{
public ContosoAdsContext() : base("name=ContosoAdsContext")
{
}
public ContosoAdsContext(string connString)
: base(connString)
{
}
public System.Data.Entity.DbSet<Ad> Ads { get; set; }
}
A classe possui dois construtores. O primeiro deles é usado pelo projeto Web e especifica o nome de uma cadeia de conexão armazenada no arquivo Web.config. O segundo construtor permite transmitir a cadeia de conexão real usada para o projeto de função de trabalho, pois ele não tem um arquivo Web.config. Você viu anteriormente onde essa cadeia de conexão estava armazenada. Posteriormente, você verá como o código recupera a cadeia de conexão quando cria uma instância da classe DbContext.
ContosoAdsWeb - Global.asax.cs
O código que é chamado do método Application_Start
criará um contêiner de blob images e uma fila images, se ainda não existirem. Esse código garante que sempre que você usar uma nova conta de armazenamento ou usar o emulador de armazenamento em um novo computador, o código cria automaticamente o contêiner e a fila de blob necessários.
O código obtém acesso à conta de armazenamento usando a cadeia de conexão de armazenamento do arquivo .cscfg .
var storageAccount = CloudStorageAccount.Parse
(RoleEnvironment.GetConfigurationSettingValue("StorageConnectionString"));
Em seguida, ele obtém uma referência para o contêiner do blob de imagens , cria o contêiner se ele ainda não existe e define permissões de acesso no novo contêiner. Por padrão, os novos contêineres permitem que somente clientes com credenciais da conta de armazenamento acessem os blobs. O site precisa que os blobs para o público para poder exibir imagens usando URLs que apontam para os blobs de imagem.
var blobClient = storageAccount.CreateCloudBlobClient();
var imagesBlobContainer = blobClient.GetContainerReference("images");
if (imagesBlobContainer.CreateIfNotExists())
{
imagesBlobContainer.SetPermissions(
new BlobContainerPermissions
{
PublicAccess =BlobContainerPublicAccessType.Blob
});
}
Um código similar obtém uma referência para a fila de imagens e cria uma nova fila. Nesse caso, nenhuma alteração de permissão é necessária.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
var imagesQueue = queueClient.GetQueueReference("images");
imagesQueue.CreateIfNotExists();
ContosoAdsWeb - _Layout.cshtml
O arquivo _Layout.cshtml define o nome do aplicativo no cabeçalho e no rodapé e cria uma entrada de menu "Ads".
ContosoAdsWeb - Views\Home\Index.cshtml
O arquivo Views\Home\Index.cshtml exibe links de categoria na home page. Os links passam o valor inteiro da enumeração Category
em uma variável querystring para a página Índice de anúncio.
<li>@Html.ActionLink("Cars", "Index", "Ad", new { category = (int)Category.Cars }, null)</li>
<li>@Html.ActionLink("Real estate", "Index", "Ad", new { category = (int)Category.RealEstate }, null)</li>
<li>@Html.ActionLink("Free stuff", "Index", "Ad", new { category = (int)Category.FreeStuff }, null)</li>
<li>@Html.ActionLink("All", "Index", "Ad", null, null)</li>
ContosoAdsWeb - AdController.cs
No arquivo AdController.cs, o construtor chama o método InitializeStorage
para criar os objetos da Biblioteca do Cliente do Armazenamento do Azure que fornecem uma API para trabalhar com blobs e filas.
Em seguida, o código obtém uma referência para o contêiner do blob de imagens como visto anteriormente em Global.asax.cs. Enquanto faz isso ele define uma política de recuperação padrão apropriada para um aplicativo Web. A política de repetição de retirada exponencial padrão pode fazer com que o aplicativo Web pare de responder por mais de um minuto em tentativas repetidas em uma falha transitória. A política de recuperação especificada aqui aguarda três segundos após cada tentativa, até três tentativas.
var blobClient = storageAccount.CreateCloudBlobClient();
blobClient.DefaultRequestOptions.RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(3), 3);
imagesBlobContainer = blobClient.GetContainerReference("images");
Código similar obtém uma referência para a fila de imagens .
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
queueClient.DefaultRequestOptions.RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(3), 3);
imagesQueue = queueClient.GetQueueReference("images");
A maior parte do código do controlador é típica para trabalhar com um modelo de dados do Entity Framework usando uma classe DbContext. Uma exceção é o método HttpPost Create
, que atualiza um arquivo e o salva no armazenamento do blob. O associador de modelo fornece um objeto HttpPostedFileBase para o método.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(
[Bind(Include = "Title,Price,Description,Category,Phone")] Ad ad,
HttpPostedFileBase imageFile)
Se o usuário selecionou um arquivo para carregamento, o código carrega o arquivo, salva o arquivo em um blob e atualiza o registro do banco de dados do anúncio com uma URL que aponta para o blob.
if (imageFile != null && imageFile.ContentLength != 0)
{
blob = await UploadAndSaveBlobAsync(imageFile);
ad.ImageURL = blob.Uri.ToString();
}
O código que não é carregado está no método UploadAndSaveBlobAsync
. Ele cria um nome de GUID para o blob, carrega e salva o arquivo e retorna uma referência para o blob salvo.
private async Task<CloudBlockBlob> UploadAndSaveBlobAsync(HttpPostedFileBase imageFile)
{
string blobName = Guid.NewGuid().ToString() + Path.GetExtension(imageFile.FileName);
CloudBlockBlob imageBlob = imagesBlobContainer.GetBlockBlobReference(blobName);
using (var fileStream = imageFile.InputStream)
{
await imageBlob.UploadFromStreamAsync(fileStream);
}
return imageBlob;
}
Depois de carregar um blob e atualizar o banco de dados, o método Create
HttpPost criará uma mensagem da fila para informar o processo back-end que uma imagem está pronta para conversão em uma miniatura.
string queueMessageString = ad.AdId.ToString();
var queueMessage = new CloudQueueMessage(queueMessageString);
await queue.AddMessageAsync(queueMessage);
O código para o método Edit
HttpPost é semelhante, exceto pelo fato de que se o usuário seleciona um novo arquivo de imagem, quaisquer blobs existentes deverão ser excluídos.
if (imageFile != null && imageFile.ContentLength != 0)
{
await DeleteAdBlobsAsync(ad);
imageBlob = await UploadAndSaveBlobAsync(imageFile);
ad.ImageURL = imageBlob.Uri.ToString();
}
O próximo exemplo mostra o código que exclui blobs quando você exclui um anúncio.
private async Task DeleteAdBlobsAsync(Ad ad)
{
if (!string.IsNullOrWhiteSpace(ad.ImageURL))
{
Uri blobUri = new Uri(ad.ImageURL);
await DeleteAdBlobAsync(blobUri);
}
if (!string.IsNullOrWhiteSpace(ad.ThumbnailURL))
{
Uri blobUri = new Uri(ad.ThumbnailURL);
await DeleteAdBlobAsync(blobUri);
}
}
private static async Task DeleteAdBlobAsync(Uri blobUri)
{
string blobName = blobUri.Segments[blobUri.Segments.Length - 1];
CloudBlockBlob blobToDelete = imagesBlobContainer.GetBlockBlobReference(blobName);
await blobToDelete.DeleteAsync();
}
ContosoAdsWeb - Views\Ad\Index.cshtml e Details.cshtml
O arquivo Index.cshtml exibe miniaturas com os outros dados de anúncio.
<img src="@Html.Raw(item.ThumbnailURL)" />
O arquivo Details.cshtml exibe a imagem em tamanho real.
<img src="@Html.Raw(Model.ImageURL)" />
ContosoAdsWeb - Views\Ad\Create.cshtml e Edit.cshtml
Os arquivos Create.cshtml e Edit.cshtml especificam a codificação de formulário que habilita o controlador a obter o objeto HttpPostedFileBase
.
@using (Html.BeginForm("Create", "Ad", FormMethod.Post, new { enctype = "multipart/form-data" }))
Um elemento <input>
informa o navegador para fornecer uma caixa de diálogo de seleção de arquivo.
<input type="file" name="imageFile" accept="image/*" class="form-control fileupload" />
ContosoAdsWorker - WorkerRole.cs - Método OnStart
O ambiente da função de trabalho do Azure chama o método OnStart
na classe WorkerRole
quando a função de trabalho é iniciada, e chama o método Run
quando o método OnStart
é concluído.
O método OnStart
obtém a cadeia de conexão do banco de dados do arquivo .cscfg e a transmite para a classe DbContext do Entity Framework. O provedor SQLClient é usado por padrão, portanto, o provedor não precisa ser especificado.
var dbConnString = CloudConfigurationManager.GetSetting("ContosoAdsDbConnectionString");
db = new ContosoAdsContext(dbConnString);
Depois disso, o método obtém uma referência para a conta de armazenamento e cria a fila e o contêiner do blob, se eles não existirem. O código para isso é semelhante àquele já visto no método da função Web Application_Start
.
ContosoAdsWorker - WorkerRole.cs - Método de execução
O método Run
é chamado quando o método OnStart
conclui seu trabalho de inicialização. O método executa um loop infinito que procura novas mensagens na fila e as processa quando chegam.
public override void Run()
{
CloudQueueMessage msg = null;
while (true)
{
try
{
msg = this.imagesQueue.GetMessage();
if (msg != null)
{
ProcessQueueMessage(msg);
}
else
{
System.Threading.Thread.Sleep(1000);
}
}
catch (StorageException e)
{
if (msg != null && msg.DequeueCount > 5)
{
this.imagesQueue.DeleteMessage(msg);
}
System.Threading.Thread.Sleep(5000);
}
}
}
Após cada interação do loop, se nenhuma mensagem foi encontrada na fila, o programa é suspenso durante um segundo. Essa suspensão evita que o trabalho incorra em tempo excessivo de CPU e custos de transação de armazenamento. A Equipe de Consultoria de Clientes da Microsoft conta a história de um desenvolvedor que esqueceu de incluir essa função de suspensão, implantou na produção e saiu de férias. Quando ele voltou, sua distração havia custado mais do que as férias.
Algumas vezes o conteúdo de uma mensagem da fila causa um erro no processamento. Esse tipo de mensagem é chamada de mensagem suspeita. Se você apenas registrasse um erro e reiniciasse o loop, poderia tentar processar essa mensagem infinitamente. Portanto, o bloco catch inclui uma instrução if que verifica quantas vezes o aplicativo tentou processar a mensagem atual. Se a contagem for superior a cinco vezes, a mensagem será excluída da fila.
ProcessQueueMessage
é chamado quando uma mensagem em fila é encontrada.
private void ProcessQueueMessage(CloudQueueMessage msg)
{
var adId = int.Parse(msg.AsString);
Ad ad = db.Ads.Find(adId);
if (ad == null)
{
throw new Exception(String.Format("AdId {0} not found, can't create thumbnail", adId.ToString()));
}
CloudBlockBlob inputBlob = this.imagesBlobContainer.GetBlockBlobReference(ad.ImageURL);
string thumbnailName = Path.GetFileNameWithoutExtension(inputBlob.Name) + "thumb.jpg";
CloudBlockBlob outputBlob = this.imagesBlobContainer.GetBlockBlobReference(thumbnailName);
using (Stream input = inputBlob.OpenRead())
using (Stream output = outputBlob.OpenWrite())
{
ConvertImageToThumbnailJPG(input, output);
outputBlob.Properties.ContentType = "image/jpeg";
}
ad.ThumbnailURL = outputBlob.Uri.ToString();
db.SaveChanges();
this.imagesQueue.DeleteMessage(msg);
}
Esse código lê o banco de dados para obter a URL da imagem, converte a imagem para uma miniatura, salva a miniatura em um blob, atualiza o banco de dados com a URL do blob da miniatura e exclui a mensagem da fila.
Observação
O código no método ConvertImageToThumbnailJPG
usa classes no namespace System.Drawing para simplificar. Entretanto, as classes nesse namespace foram projetadas para uso nos formulários do Windows. Elas não têm suporte para uso em um serviço Windows ou ASP.NET. Para obter mais informações sobre opções de processamento de imagem, consulte Geração dinâmica de imagem e Visão aprofundada de redimensionamento de imagens.
Solução de problemas
Caso algo não funcione enquanto você estiver seguindo as instruções nesse tutorial, veja a seguir alguns erros comuns e como resolvê-los.
ServiceRuntime.RoleEnvironmentException
O objeto RoleEnvironment
é fornecido pelo Azure quando você executa uma aplicação no Azure ou quando você executa localmente usando o Emulador de Computação do Azure. Se você receber esse erro quando estiver executando localmente, certifique-se de definir o projeto ContosoAdsCloudService como o projeto de inicialização. Essa configuração faz com que o projeto seja executado usando o Emulador de Computação do Azure.
Uma das coisas para as quais o aplicativo usa o RoleEnvironment do Azure é para obter os valores de cadeia de conexão armazenados nos arquivos .cscfg e, portanto, uma nova causa dessa exceção é uma cadeia de conexão perdida. Certifique-se de que criou a configuração StorageConnectionString para as configurações local e de nuvem no projeto ContosoAdsWeb, e de que criou as duas cadeias de conexão para as ambas as configurações do projeto ContosoAdsWorker. Se você fizer uma pesquisa Localizar Tudo por StorageConnectionString em toda a solução, deverá vê-lo nove vezes em seis arquivos.
Não é possível substituir a porta xxx. O valor abaixo do mínimo permitido para a nova porta é de 8080 para o protocolo http
Tente alterar o número da porta usado pelo projeto Web. Clique com o botão direito do mouse no projeto ContosoAdsWeb e, em seguida, selecione Propriedades. Escolha a guia Web e altere o número da porta na configuração do URL do Projeto.
Para obter uma outra alternativa que possa resolver o problema, consulte a seção a seguir.
Outros erros que podem ocorrer ao executar localmente
Por padrão, os novos projetos de serviço de nuvem usam o Emulador de Computação expresso do Azure para simular o ambiente do Azure. O Emulador de Computação do Azure é uma versão leve do emulador de computação completo e, sob algumas condições, o emulador completo funciona quando a versão expressa não funciona.
Para alterar o projeto para usar o emulador completo, clique com o botão direito do mouse no projeto da ContosoAdsCloudService e, em seguida, selecione Propriedades. Na janela Propriedades, selecione a guia Web e, em seguida, selecione o botão de opção Usar o Emulador Completo.
Para executar o aplicativo com o emulador completo, abra o Visual Studio com privilégios de administrador.
Próximas etapas
O aplicativo Contoso Ads foi intencionalmente simplificado para um tutorial de introdução. Por exemplo, não implementa injeção de dependência ou padrões de repositório e unidade de trabalho. Ele não usa uma interface para registro, não usa Migrações do Code First EF para gerenciar alterações no modelo de dados ou Resiliência de Conexão EF para gerenciar erros transitórios de rede e assim por diante.
Para obter informações sobre como desenvolver para a nuvem, consulte Criando aplicativos de nuvem do mundo real no Azure.
Para obter mais informações, consulte os seguintes recursos: