Introdução aos Serviços de Nuvem do Azure (clássicos) e ASP.NET
Descrição geral
Importante
Os Serviços na Nuvem (clássicos) foram preteridos para todos os clientes a partir de 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. Novas implantações devem usar o novo modelo de implantação baseado no Azure Resource Manager Serviços de Nuvem do Azure (suporte estendido).
Este tutorial mostra como criar um aplicativo .NET de várias camadas com um front-end MVC (Model-View-Controller) do ASP.NET e implantá-lo em um serviço de nuvem do Azure. A aplicação utiliza a Base de Dados SQL do Azure, o serviço Blob do Azure e o serviço Fila do Azure. Você pode baixar o projeto do Visual Studio da Galeria de Códigos do Microsoft Developer Network (MSDN).
O tutorial mostra como compilar e executar a aplicação localmente, como implementá-la no Azure e executá-la na cloud e como compilá-la do zero. Pode começar por compilar do zero e, posteriormente, realizar os passos de teste e implementação, se preferir.
Aplicação de Anúncios da Contoso
A aplicação é um BBS de publicidade. Os utilizadores criam um anúncio através da introdução de texto e carregamento de uma imagem. Podem ver uma lista de anúncios com imagens em miniatura e ver a imagem de tamanho completo quando selecionarem um anúncio para ver os detalhes.
A aplicação utiliza o padrão de trabalho centrado em filas para transferir o trabalho intensivo da CPU de criar 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 num serviço em 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 utiliza WebJobs, consulte Introdução ao SDK de WebJobs do Azure. Para obter informações sobre como escolher os serviços que melhor se ajustam ao seu cenário, consulte Serviço de Aplicativo do Azure, Serviços de Nuvem e comparação de máquinas virtuais.
Objetivos de aprendizagem
- Como ativar o computador para a programação do Azure instalando o Azure SDK.
- Como criar um projeto de serviço em nuvem do Visual Studio com uma função da Web e uma função de trabalho do 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 num serviço em nuvem do Azure e testá-lo utilizando uma conta do Storage do Azure.
- Como carregar ficheiros e armazená-los no serviço Blob do Azure.
- Como utilizar o serviço Fila do Azure para a comunicação entre camadas.
Pré-requisitos
O tutorial parte do princípio de que compreende os conceitos básicos dos Cloud Services do Azure como a terminologia função da Web e função de trabalho. Também parte do princípio de que sabe como trabalhar com o MVC do ASP.NET ou com projetos de Formulários Web no Visual Studio. A aplicação de exemplo utiliza o MVC, mas a maioria do tutorial também se aplica aos Formulários 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 tiver uma conta, pode ativar os seus benefícios de subscritor MSDN ou inscrever-se numa avaliação gratuita.
As instruções do tutorial funcionam com qualquer um dos seguintes produtos:
- 2013 Visual Studio
- 2015 Visual Studio
- Visual Studio 2017
- Visual Studio 2019
Se não tiver nenhum destes produtos, o Visual Studio poderá ser instalado automaticamente ao instalar o Azure SDK.
Arquitetura da aplicação
O aplicativo armazena anúncios em um banco de dados SQL, usando o Entity Framework Code First para criar as tabelas e acessar os dados. Para cada anúncio, a base de dados armazena dois URLs, um para a imagem de tamanho completo e outro para a miniatura.
Quando um utilizador carrega uma imagem, o front-end em execução numa função da Web armazena a imagem num blob do Azure e armazena as informações do anúncio na base de dados com um URL que aponta para o blob. Ao mesmo tempo, escreve uma mensagem para uma fila do Azure. Um processo de back-end em execução numa função de trabalho consulta periodicamente a fila para verificar se existem novas mensagens. Quando for apresentada uma nova mensagem, a função de trabalho cria uma miniatura dessa imagem e atualiza o campo da base de dados de URLs de miniaturas desse anúncio. O diagrama seguinte mostra como interagem as partes da aplicação.
Configurar o ambiente de desenvolvimento
Para começar, configure seu ambiente de desenvolvimento com o Visual Studio e o Azure SDK.
O Visual Studio 2019 inclui o SDK do Azure. Se você estiver usando o Visual Studio 2019, nenhuma configuração adicional será necessária para o ambiente de desenvolvimento.
No Visual Studio 2015, clique na seguinte ligação para instalar o Azure SDK para Visual Studio 2015.
No Visual Studio 2013, clique na seguinte ligação para instalar o Azure SDK 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.
Nota
Dependendo do número de dependências SDK que já possui no seu computador, instalar o SDK pode demorar muito tempo, de alguns minutos a meia hora ou mais.
Transferir e executar a solução concluída
Transfira e deszipe a solução concluída.
Inicie o Visual Studio.
No menu Ficheiro, escolha Abrir Projeto, navegue para onde transferiu a solução e, em seguida, abra o ficheiro da 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. Para tal, vá para a caixa de diálogo Gerir Pacotes NuGet da Solução e clique no botão Restaurar na parte superior direita.
No Explorador de Soluções, certifique-se de que ContosoAdsCloudService é selecionado como o projeto de arranque.
Se estiver a utilizar o Visual Studio 2015 ou superior, altere a cadeia de ligação do SQL Server no ficheiro Web.config da aplicação do projeto ContosoAdsWeb e no ficheiroServiceConfiguration.Local.cscfg do projeto ContosoAdsCloudService. Em cada caso, altere “(localdb)\v11.0” para “(localdb)\MSSQLLocalDB”.
Para executar o aplicativo, pressione CTRL+F5.
Quando executa localmente um projeto do serviço em nuvem, o Visual Studio invoca automaticamente o emulador de computação do Azure e o emulador de armazenamento do Azure. O emulador de computação utiliza os recursos do computador para simular os ambientes da função da Web e da função de trabalho. O emulador de armazenamento utiliza uma base de dados SQL Server Express LocalDB para simular o armazenamento na nuvem do Azure.
Quando executar um projeto do serviço em nuvem pela primeira vez, demorará um minuto ou mais até que os emuladores arranquem. Quando o arranque dos emuladores estiver concluído, o browser predefinido é aberto na home page da aplicação.
Selecione Criar um anúncio.
Introduza alguns dados de teste, selecione uma imagem .jpg para carregar e, em seguida, selecione Criar.
O aplicativo vai para a página Índice, mas não mostra uma miniatura do novo anúncio porque esse processamento ainda não aconteceu.
Aguarde um momento e, em seguida, atualize a página Índice para ver a miniatura.
Selecione Detalhes do anúncio para ver a imagem em tamanho real.
A aplicação tem estado a ser executada inteiramente no computador local, sem ligação com a nuvem. O emulador de armazenamento armazena os dados de fila e blob numa base de dados do SQL Server Express LocalDB. A aplicação armazena os dados do anúncio noutra base de dados LocalDB. O Entity Framework Code First criou automaticamente a base de dados de anúncios da primeira vez que a aplicação Web tentou aceder à mesma.
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 ele é executado na nuvem. Se quisesse continuar a executar a aplicação localmente, mas utilizar recursos da base de dados e do armazenamento na cloud, poderia fazê-lo. É apenas uma questão de definir cadeias de conexão, o que você vê como fazer.
Implementar a aplicação no Azure
Você executa as seguintes etapas para executar o aplicativo na nuvem:
- Crie um serviço em 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 ele for executado no Azure.
- Configure a solução para utilizar a sua conta do Storage do Azure, quando é executada no Azure.
- Implemente o projeto no serviço em nuvem do Azure.
Criar um serviço em nuvem do Azure
Um serviço de nuvem do Azure é o ambiente em que o aplicativo é executado.
No browser, abra o portal do Azure.
Selecione Criar um recurso > Compute > Cloud Service.
Na caixa de entrada de nome DNS (Sistema de Nomes de Domínio), insira um prefixo de URL para o serviço de nuvem.
Este URL tem de ser exclusivo. 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 pretende implementar a aplicação.
Este campo especifica em qual datacenter seu serviço de nuvem está hospedado. Para uma aplicação de produção, deverá escolher a região mais próxima dos seus clientes. Para este tutorial, escolha a região mais próxima de si.
Selecione Criar.
Na imagem seguinte, é criado um serviço cloud com o 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 > Banco de Dados SQL de Bancos de Dados>.
Na caixa Nome da Base de Dados, introduza contosoads.
No grupo Recursos, escolha Usar existente e selecione o grupo de recursos usado para o serviço de nuvem.
Na imagem a seguir, selecione Servidor - Definir configurações necessárias e Criar um novo servidor.
Em alternativa, se a sua subscrição já tiver um servidor, pode selecionar esse servidor na lista pendente.
Na caixa Nome do servidor , introduza csvccontosodbserver.
Introduza um Nome de Início de Sessão e Palavra-Passe de administrador.
Se tiver selecionado Criar um novo servidor, não introduzirá um nome e palavra-passe existentes aqui. Deverá introduzir um novo nome e palavra-passe, que definirá agora para utilizar posteriormente quando aceder à base de dados. Se você selecionou um servidor criado anteriormente, o portal solicitará a senha para a conta de usuário administrativo que você já criou.
Escolha a mesma Localização que escolheu para o serviço cloud.
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 dentro de um datacenter é gratuita.
Marque Permitir o acesso dos serviços do Azure ao servidor.
Selecione Selecionar para o novo servidor.
Selecione Criar.
Criar uma conta de armazenamento do Azure
Uma conta do Storage do Azure fornece recursos para armazenar dados de fila e blob na nuvem.
Numa aplicação real, normalmente criaria contas separadas para os dados da aplicação versus os dados de registo e contas separadas para os dados de teste versus os dados de produção. Para este tutorial, você usa apenas uma conta.
No portal do Azure, selecione Criar uma conta de armazenamento de > recursos > - blob, arquivo, tabela, fila.
Na caixa Nome, introduza um prefixo de URL.
Esse prefixo mais o texto que você vê na caixa é o URL exclusivo para sua conta de armazenamento. Se o prefixo inserido já estiver em uso por outra pessoa, escolha um prefixo diferente.
Defina o Modelo de implementação como Clássico.
Defina a lista pendente Replicação para Armazenamento localmente redundante.
Quando a georreplicação está ativada para uma conta de armazenamento, o conteúdo armazenado é replicado para um datacenter secundário para ativar a ativação pós-falha, se ocorrer um desastre grave na localização primária. A georreplicação pode implicar custos adicionais. Para contas de teste e de desenvolvimento, normalmente não deseja pagar a georreplicação. Para obter mais informações, consulte Criar, gerir ou eliminar uma conta do Storage.
No grupo Recursos, selecione Usar existente e selecione o grupo de recursos usado para o serviço de nuvem.
Defina a Localização na lista pendente para a mesma região que selecionou para o serviço cloud.
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 dentro de um datacenter é gratuita.
Os grupos de afinidades do Azure fornecem um mecanismo para minimizar a distância entre os recursos num data center, o que poderá reduzir a latência. Este tutorial não usa grupos de afinidade. Para obter mais informações, consulte Como Criar um Grupo de Afinidades no Azure.
Selecione Criar.
Na imagem, é criada uma conta do Storage com o 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 sua própria cadeia de conexão de banco de dados, e cada um 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 a função de trabalho.
Nota
Nesta secção e na secção seguinte, as credenciais serão armazenadas nos ficheiros de projeto. Não armazene dados confidenciais em repositórios de código-fonte públicos.
No projeto ContosoAdsWeb, abra o ficheiro de transformação Web.Release.config para o ficheiro Web.config da aplicação, elimine o bloco de comentários que contém um elemento
<connectionStrings>
e cole o seguinte código no seu lugar.<connectionStrings> <add name="ContosoAdsContext" connectionString="{connectionstring}" providerName="System.Data.SqlClient" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/> </connectionStrings>
Deixe o ficheiro aberto para edição.
No portal do Azure, escolha Bancos de Dados SQL no painel esquerdo, selecione o banco de dados criado para este tutorial e selecione Mostrar cadeias de conexão.
O portal apresenta as cadeias de ligação, com um marcador de posição para a palavra-passe.
No ficheiro de transformação Web.Release.config, elimine
{connectionstring}
e cole no seu lugar a cadeia de ligação ADO.NET a partir do portal do Azure.Na cadeia de ligação que colou no ficheiro de transformação Web.Release.config, substitua
{your_password_here}
pela palavra-passe que criou para a nova SQL Database.Guarde o ficheiro.
Selecione e copie a cadeia de ligação (sem as aspas) para utilização nos passos seguintes 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 selecione Propriedades.
Escolha a guia Configurações .
Altere Configuração do Serviço para Nuvem.
Selecione o campo Valor para a definição
ContosoAdsDbConnectionString
e, em seguida, cole a cadeia de ligação que copiou na secção anterior do tutorial.Guardar as suas alterações.
Configurar a solução para utilizar a conta do Storage do Azure quando for executada no Azure
As cadeias de ligação da conta do Storage do Azure para o projeto da função da Web e para o projeto da função de trabalho são armazenadas nas definições de ambiente no projeto do serviço em 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 função Web e de trabalho.
No Gerenciador de Soluções, clique com o botão direito do mouse em ContosoAdsWeb em Funções no projeto ContosoAdsCloudService e selecione Propriedades.
Escolha a guia Configurações. Na caixa suspensa Configuração do serviço, escolha 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.
Guardar as suas alterações.
Siga o mesmo procedimento utilizado para a cadeia de ligação
StorageConnectionString
para definir a cadeia de ligaçãoMicrosoft.WindowsAzure.Plugins.Diagnostics.ConnectionString
.Esta cadeia de ligação é utilizada para registo.
Siga o mesmo procedimento utilizado para a função ContosoAdsWeb para definir ambas as cadeias de ligação para a função ContosoAdsWorker. Não se esqueça de definir a Configuração do Serviço para 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 no projeto ContosoAdsCloudService:
- ServiceDefinition.csdef – define os nomes de definição.
- ServiceConfiguration.Cloud.cscfg – fornece valores para quando a aplicação é executada na nuvem.
- ServiceConfiguration.Cloud.cscfg – fornece valores para quando a aplicação é executada localmente.
Por exemplo, ServiceDefinition.csdef inclui as seguintes definições:
<ConfigurationSettings>
<Setting name="StorageConnectionString" />
<Setting name="ContosoAdsDbConnectionString" />
</ConfigurationSettings>
E o ficheiro ServiceConfiguration.Cloud.cscfg inclui os valores que introduziu para essas definiçõ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 <Instances>
configuração especifica o número de máquinas virtuais nas quais o Azure executa o código da função de trabalho. A secção Passos seguintes inclui ligações para mais informações sobre como ampliar um serviço em nuvem.
Implementar o projeto no Azure
No Explorador de Soluções, clique com o botão direito do rato no projeto de nuvem ContosoAdsCloudService e selecione Publicar.
Na etapa Entrar do assistente Publicar Aplicativo do Azure, selecione Avançar.
Na etapa Configurações do assistente, selecione Avançar.
As predefinições no separador Avançado podem ser utilizadas neste tutorial. Para obter informações sobre o separador Avançado, consulte Publicar Assistente da Aplicação Azure.
Na etapa Resumo, selecione Publicar.
A janela Registo de Atividade do Azure é aberta no Visual Studio.
Escolha o ícone de seta para a direita para expandir os detalhes da implantação.
A implementação pode demorar 5 minutos ou mais para ser concluída.
Quando o status da implantação estiver concluído, selecione a URL do aplicativo Web para iniciar o aplicativo.
Pode agora testar a aplicação através da criação, visualização e edição de alguns anúncios, como fez quando executou a aplicação localmente.
Nota
Quando tiver terminado o teste, elimine ou pare o serviço em nuvem. Mesmo se não estiver a utilizar o serviço em nuvem, este estará a acumular encargos, porque os recursos de máquinas virtuais estão reservados para o mesmo. E, se o deixar a funcionar, qualquer pessoa que encontre o URL pode criar e ver anúncios. No portal do Azure, aceda ao separador Descrição Geral do serviço cloud e clique no botão Eliminar na parte superior da página. Se apenas pretender impedir temporariamente que outras pessoas acedam ao site, clique em Parar. Nesse caso, os encargos irão continuar a acumular. Pode seguir um procedimento semelhante para eliminar a SQL Database e a conta do Storage quando já não necessitar delas.
Criar a aplicação do zero
Se você ainda precisa baixar o aplicativo completo, faça isso agora. Copie os arquivos do projeto baixado para o novo projeto.
A criação da aplicação de Anúncios da Contoso envolve os seguintes passos:
- Criar uma solução do Visual Studio do serviço em nuvem.
- Atualizar e adicionar pacotes NuGet.
- Definir referências do projeto.
- Configurar cadeias de ligação.
- Adicionar ficheiros de código.
Após criar a solução, deverá consultar o código que é exclusivo para os projetos do serviço em nuvem e para os blobs e filas do Azure.
Criar uma solução do Visual Studio do serviço em nuvem
No Visual Studio, selecione Novo Projeto no menu Ficheiro.
No painel esquerdo da caixa de diálogo Novo Projeto, expanda Visual c#, escolha os modelos Nuvem e, em seguida, escolha o modelo Serviço em Nuvem do Azure.
Nomeie o projeto e a solução como ContosoAdsCloudService e selecione OK.
Na caixa de diálogo Novo Serviço em Nuvem do Azure, adicione uma função da Web e uma função de trabalho. Nomeie a função da Web ContosoAdsWeb e a função de trabalho ContosoAdsWorker. (Utilize o ícone de lápis no painel direito para alterar os nomes predefinidos das funções.)
Quando vir a caixa de diálogo Novo Projeto ASP.NET para a função Web, escolha o modelo MVC e, em seguida, 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 ASP.NET Projeto, selecione OK.
No Explorador de Soluções, clique com o botão direito do rato na solução (não num dos 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 como ContosoAdsCommon e selecione OK.
Tem de referenciar o contexto do Entity Framework e o modelo de dados dos projetos da função Web e de trabalho. Como alternativa, pode definir as classes relacionadas a EF no projeto da função da Web e fazer referência a esse projeto no projeto da função de trabalho. Mas, na abordagem alternativa, o projeto da função de trabalho terá uma referência a assemblagens Web desnecessária.
Atualizar e adicionar pacotes NuGet
Abra a caixa de diálogo Gerir Pacotes NuGet da 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 nos quais atualizá-lo e, em seguida, selecione Atualizar.
A biblioteca de cliente de armazenamento é atualizada com mais freqüência do que os modelos de projeto do Visual Studio, portanto, você pode achar que a versão em um projeto recém-criado precisa ser atualizada.
Na parte superior da janela, selecione Procurar.
Localize o pacote NuGet EntityFramework e instale-o nos três projetos.
Localize o pacote NuGet Microsoft.WindowsAzure.ConfigurationManager e instale-o num projeto da função de trabalho.
Definir referências do projeto
No projeto ContosoAdsWeb, defina uma referência para o projeto ContosoAdsCommon. Clique com o botão direito do mouse no projeto ContosoAdsWeb e selecione Referências - Adicionar referências. Na caixa de diálogo Gerenciador de Referências, selecione Solução – Projetos no painel esquerdo, selecione 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
.Esta assemblagem é utilizada pelo back-end para converter imagens em miniaturas.
Configurar cadeias de ligação
Nesta secção, deverá configurar o Armazenamento do Azure e as cadeias de ligação SQL para testar localmente. As instruções de implementação anteriormente descritas no tutorial explicam como configurar as cadeias de ligação para quando a aplicação é executada na nuvem.
No projeto ContosoAdsWeb, abra o ficheiro Web.config da aplicação e insira o seguinte elemento
connectionStrings
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 estiver a utilizar o Visual Studio 2015 ou superior, substitua “v11.0” por “MSSQLLocalDB”.
Guardar as suas alterações.
No projeto ContosoAdsCloudService, clique com o botão direito do mouse em ContosoAdsWeb em Funções e selecione Propriedades.
Na janela de propriedades ContosoAdsWeb [Função], selecione a guia Configurações e selecione Adicionar Configuração.
Deixe Configuração do Serviço definida para Todas as Configurações.
Adicione uma definição denominada StorageConnectionString. Defina o Tipo para ConnectionString e o Valor para UseDevelopmentStorage = true.
Guardar as suas alterações.
Siga o mesmo procedimento para adicionar uma cadeia de ligação de armazenamento nas propriedades da função ContosoAdsWorker.
Ainda na janela de propriedades ContosoAdsWorker [Função], adicione outra cadeia de conexão:
Nome: ContosoAdsDbConnectionString
Tipo: cadeia
Valor: cole a mesma cadeia de ligação utilizada para o projeto da função da Web. (O exemplo a seguir é para Visual Studio 2013. Não se esqueça de alterar a Fonte de Dados se você 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 ficheiros de código
Nesta secção, deverá copiar os ficheiros de código da solução transferida para a solução nova. 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 do mouse no projeto ou pasta e selecione Adicionar - Item Existente. Selecione os arquivos desejados e, em seguida, selecione Adicionar. Se lhe for perguntado se pretende substituir ficheiros existentes, selecione Sim.
No projeto ContosoAdsCommon, elimine o ficheiro Class1.cs e adicione no seu lugar os ficheiros Ad.cs e ContosoAdscontext.cs do projeto transferido.
No projeto ContosoAdsWeb, adicione os seguintes ficheiros do projeto transferido.
- Global.asax.cs.
- Na pasta Views\Shared: _Layout.cshtml.
- Na pasta Vistas\Início: Index.cshtml.
- Na pasta Controladores: AdController.cs.
- Na pasta Vistas\Anúncio (crie a pasta primeiro): cinco ficheiros .cshtml.
No projeto ContosoAdsWorker, adicione WorkerRole.cs do projeto transferido.
Agora você pode criar e executar o aplicativo conforme instruído anteriormente no tutorial, e o aplicativo usa recursos de emulador de armazenamento e banco de dados local.
As secções seguintes explicam o código relacionado para trabalhar com o ambiente, blobs e filas do Azure. Este tutorial não explica como criar controladores MVC e exibições usando scaffolding, como escrever código do Entity Framework que funciona com 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 estes tópicos, consulte os recursos seguintes:
ContosoAdsCommon – Ad.cs
O ficheiro Ad.cs define uma enumeração de categorias de anúncio e uma classe de entidade POCO para as informações do anúncio.
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 tem dois construtores. O primeiro é utilizado pelo projeto Web e especifica o nome de uma cadeia de ligação que está armazenada no ficheiro Web.config. O segundo construtor permite-lhe transmitir a cadeia de ligação atual utilizada pelo projeto de função de trabalho, uma vez que não tem um ficheiro Web.config. Você viu anteriormente onde essa cadeia de conexão foi armazenada. Mais tarde, você verá como o código recupera a cadeia de conexão quando instancia a classe DbContext.
ContosoAdsWeb – Global.asax.cs
O código que é chamado pelo método Application_Start
cria um contentor de blob de imagens e uma fila de imagens 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 criará automaticamente o contêiner de blob e a fila necessários.
O código obtém acesso à conta do Storage utilizando a cadeia de ligação de armazenamento no ficheiro .cscfg.
var storageAccount = CloudStorageAccount.Parse
(RoleEnvironment.GetConfigurationSettingValue("StorageConnectionString"));
Em seguida, obtém uma referência para o contentor de blob de imagens, cria o contentor, se ainda não existir, e define as permissões de acesso no novo contentor. Por predefinição, os novos contentores permitem apenas que os clientes com credenciais de conta do Storage acedam aos blobs. O site necessita de blobs para ser público, para poder apresentar imagens com URLs que apontem para os blobs de imagens.
var blobClient = storageAccount.CreateCloudBlobClient();
var imagesBlobContainer = blobClient.GetContainerReference("images");
if (imagesBlobContainer.CreateIfNotExists())
{
imagesBlobContainer.SetPermissions(
new BlobContainerPermissions
{
PublicAccess =BlobContainerPublicAccessType.Blob
});
}
Um código semelhante obtém uma referência para a fila de imagens e cria uma nova fila. Neste caso, não é necessário alterar as permissões.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
var imagesQueue = queueClient.GetQueueReference("images");
imagesQueue.CreateIfNotExists();
ContosoAdsWeb - _Layout.cshtml
O ficheiro _Layout.cshtml define o nome da aplicação no cabeçalho e no rodapé e cria uma entrada de menu “Anúncios”.
ContosoAdsWeb – Views\Home\Index.cshtml
O ficheiro Views\Home\Index.cshtml apresenta ligações das categorias na página inicial. As ligações passam o valor inteiro da enumeração Category
numa variável querystring para a página Índice de Anúncios.
<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 ficheiro AdController.cs, o construtor chama o método InitializeStorage
para criar objetos de Biblioteca de Clientes 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 contentor de blob de imagens, conforme mostrado anteriormente no Global.asax.cs. Ao fazer isso, define uma política de repetição predefinida adequada para uma aplicação Web. A política de repetição de backoff exponencial padrão pode fazer com que o aplicativo Web pare de responder por mais de um minuto em repetidas tentativas por uma falha transitória. A política de repetiçã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");
Um código semelhante 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 utilizando uma classe DbContext. Uma exceção é o método HttpPost Create
, que carrega um ficheiro e guarda-o no Blob Storage. A conversão de modelos 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 utilizador tiver selecionado um ficheiro para carregar, o código carrega o ficheiro, guarda-o num blob e atualiza o registo da base de dados do Anúncio com um 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 suporta o carregamento está no método UploadAndSaveBlobAsync
. Cria um nome de GUID para o blob, carrega e guarda o ficheiro e devolve uma referência para o blob guardado.
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 do método HttpPost Create
carregar um blob e atualizar a base de dados, cria uma mensagem de fila para informar esse processo de back-end de que uma imagem está pronta para conversão para uma miniatura.
string queueMessageString = ad.AdId.ToString();
var queueMessage = new CloudQueueMessage(queueMessageString);
await queue.AddMessageAsync(queueMessage);
O código do método HttpPost Edit
é semelhante, à exceção de que se o utilizador selecionar um novo ficheiro de imagem, todos os blobs existentes terão de ser eliminados.
if (imageFile != null && imageFile.ContentLength != 0)
{
await DeleteAdBlobsAsync(ad);
imageBlob = await UploadAndSaveBlobAsync(imageFile);
ad.ImageURL = imageBlob.Uri.ToString();
}
O exemplo seguinte mostra o código que elimina os blobs quando elimina 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 ficheiro Index.cshtml apresenta miniaturas com os outros dados do anúncio.
<img src="@Html.Raw(item.ThumbnailURL)" />
O ficheiro Details.cshtml apresenta a imagem de tamanho completo.
<img src="@Html.Raw(Model.ImageURL)" />
ContosoAdsWeb – Views\Ad\Create.cshtml e Edit.cshtml
Os ficheiros Create.cshtml e Edit.cshtml especificam a codificação de formulário que permite que o controlador obtenha o objeto HttpPostedFileBase
.
@using (Html.BeginForm("Create", "Ad", FormMethod.Post, new { enctype = "multipart/form-data" }))
Um elemento <input>
indica ao browser para fornecer uma caixa de diálogo de seleção de ficheiros.
<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 está a iniciar e chama o método Run
quando o método OnStart
terminar.
O método OnStart
obtém a cadeia de ligação da base de dados no ficheiro .cscfg e passa-a 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 o contentor de blobs e a fila, caso não existam. O código é semelhante ao que já vimos no método Application_Start
da função da Web.
ContosoAdsWorker - WorkerRole.cs - método Run
O método Run
é chamado quando o método OnStart
termina o trabalho de inicialização. O método executa um ciclo infinito que controla a existência de novas mensagens de fila e processa-as quando chegarem.
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 iteração do ciclo, se não for encontrada nenhuma mensagem de fila, o programa permanecerá suspenso durante um segundo. Essa suspensão impede que a função de trabalho incorra em tempo excessivo de CPU e custos de transação de armazenamento. A Equipe de Consultoria ao Cliente da Microsoft conta uma história sobre um desenvolvedor que esqueceu de incluir essa função de suspensão, implantou na produção e partiu para férias. Quando voltaram, a fiscalização custou mais do que as férias.
Por vezes, o conteúdo de uma mensagem de fila causa um erro no processamento. Esse tipo de mensagem é chamada de mensagem venenosa. Se você simplesmente registrou um erro e reiniciou o loop, você pode infinitamente tentar processar essa mensagem. 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 é encontrada uma mensagem de fila.
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);
}
Este código lê a base de dados para obter o URL da imagem, converte a imagem numa miniatura, guarda a miniatura num blob, atualiza a base de dados com o URL do blob de miniaturas e elimina a mensagem da fila.
Nota
O código no método ConvertImageToThumbnailJPG
utiliza classes no espaço de nomes System.Drawing por uma questão de simplicidade. No entanto, as classes neste espaço de nomes foram concebidas para utilização com o Windows Forms. Não são suportadas para utilização num serviço Windows ou ASP.NET. Para obter mais informações sobre as opções de processamento de imagens, consulte Geração de Imagens Dinâmicas e Redimensionamento de Imagens Profundas.
Resolução de Problemas
No caso de algo não funcionar enquanto está a seguir as instruções deste tutorial, apresentamos a seguir alguns erros comuns e como resolvê-los.
ServiceRuntime.RoleEnvironmentException
O RoleEnvironment
objeto é fornecido pelo Azure quando você executa um aplicativo no Azure ou quando 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 a aplicação utiliza o RoleEnvironment do Azure é para obter os valores da cadeia de ligação que estão armazenados nos ficheiros .cscfg. Assim, outra causa desta exceção é uma cadeia de ligação em falta. Certifique-se de que criou a definição StorageConnectionString para ambas as configurações Nuvem e Local no projeto ContosoAdsWeb e de que criou ambas as cadeias de ligação para ambas as configurações que criou no projeto ContosoAdsWorker. Se você fizer uma pesquisa Find All para StorageConnectionString em toda a solução, deverá vê-la nove vezes em seis arquivos.
Não é possível substituir para a porta xxx. Nova porta abaixo do valor mínimo permitido 8080 para o protocolo http
Experimente alterar o número da porta utilizado pelo projeto Web. Clique com o botão direito do mouse no projeto ContosoAdsWeb e selecione Propriedades. Escolha a guia Web e altere o número da porta na configuração URL do projeto.
Para obter outra alternativa para resolver o problema, consulte a secção seguinte.
Outros erros ao executar localmente
Por padrão, os novos projetos de serviço de nuvem usam o Emulador de Computação do Azure Express 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 ContosoAdsCloudService e selecione Propriedades. Na janela Propriedades, selecione a guia Web e, em seguida, selecione o botão de opção Usar emulador completo.
Para executar a aplicação com o emulador completo, terá de abrir o Visual Studio com privilégios de administrador.
Próximos passos
O aplicativo Contoso Ads é intencionalmente simplificado para um tutorial de introdução. Por exemplo, ele não implementa a injeção de dependência ou o repositório e a unidade de padrões de trabalho. Ele não usa uma interface para registro, não usa as migrações do EF Code First para gerenciar alterações de modelo de dados ou a resiliência de conexão do EF para gerenciar erros de rede transitórios e assim por diante.
Para obter informações gerais sobre como desenvolver para a nuvem, consulte Compilar Aplicações na Nuvem Reais com o Azure.
Para obter mais informações, consulte os seguintes recursos: