Introduzione ad Azure Servizi cloud (versione classica) e ASP.NET
Panoramica
Importante
Servizi cloud (versione classica) è ora deprecato per tutti i clienti a partire dal 1° settembre 2024. Eventuali distribuzioni esistenti in esecuzione saranno arrestate e chiuse da Microsoft e i dati andranno persi in modo permanente a partire da ottobre 2024. Le nuove distribuzioni devono usare il nuovo modello di distribuzione basato su Azure Resource Manager Azure Servizi cloud (supporto esteso).
Questa esercitazione illustra come creare un'applicazione .NET multilivello con un front-end MVC (Model-View-Controller) ASP.NET e distribuirla in un servizio cloud di Azure. L'applicazione usa il database SQL di Azure, il servizio BLOB di Azure e il Servizio di accodamento di Azure. È possibile scaricare il progetto di Visual Studio da Microsoft Developer Network (MSDN) Code Gallery.
Questa esercitazione illustra come compilare ed eseguire localmente l'applicazione, come distribuirla in Azure ed eseguirla nel cloud e come creare un'applicazione completamente nuova. È possibile iniziare creando un'applicazione completamente nuova, quindi eseguire i passaggi relativi a test e distribuzione in un secondo momento, se si preferisce.
Applicazione Contoso Ads
Questa applicazione è un BBS pubblicitario. Gli utenti creano un'inserzione tramite l'immissione di testo e il caricamento di un'immagine. Possono visualizzare un elenco di annunci con immagini di anteprima e visualizzare l'immagine con le dimensioni originali quando selezionano un annuncio per vederne i dettagli.
L'applicazione usa il modello di lavoro incentrato sulle code per delegare a un processo back-end il lavoro di creazione delle anteprime, che comporta un utilizzo elevato della CPU.
Architettura alternativa: servizio app e WebJobs
Questa esercitazione mostra come eseguire front-end e back-end in un servizio cloud di Azure. In alternativa, si può eseguire il front-end in un servizio app di Azure e usare la funzionalità Processi Web per il back-end. Per un'esercitazione che usa Processi Web, vedere Introduzione all'uso dell'SDK di Processi Web di Azure. Per informazioni su come scegliere i servizi ideali per lo scenario specifico, vedere Confronto tra Servizio app di Azure, Macchine virtuali, Service Fabric e Servizi cloud.
Obiettivi di apprendimento
- Abilitare il sistema per lo sviluppo in Azure installando Azure SDK.
- Creare un progetto di servizio cloud di Visual Studio con un ruolo Web MVC ASP.NET e un ruolo di lavoro.
- Testare il progetto di servizio cloud localmente, tramite l'emulatore di archiviazione di Azure.
- Pubblicare il progetto cloud in un servizio cloud di Azure e testarlo tramite un account di archiviazione di Azure.
- Caricare file e archiviarli nel servizio BLOB di Azure.
- Usare il servizio di accodamento di Azure per la comunicazione tra livelli.
Prerequisiti
Nell'esercitazione si presuppone che l'utente abbia familiarità con i concetti di base relativi ai servizi cloud di Azure, ad esempio con la terminologia ruolo Web e ruolo di lavoro. Si presuppone anche che si sia in grado di usare progetti MVC ASP.NET o Web Form in Visual Studio. L'applicazione di esempio usa MVC, ma la maggior parte dell'esercitazione è applicabile anche a Web Form.
È possibile eseguire l'app in locale senza una sottoscrizione di Azure, ma ne è necessaria una per distribuire l'applicazione nel cloud. Se non si dispone di un account, è possibile attivare i benefici della sottoscrizione MSDN oppure iscriversi per ottenere una versione di valutazione gratuita.
Le istruzioni dell'esercitazione sono applicabili a uno qualsiasi dei prodotti seguenti:
- Visual Studio 2013
- Visual Studio 2015
- Visual Studio 2017
- Visual Studio 2019
Se uno di questi prodotti non è disponibile, Visual Studio potrà essere installato automaticamente quando si installa Azure SDK.
Architettura dell'applicazione
L'app archivia inserzioni pubblicitarie in un database SQL usando Code First di Entity Framework per creare le tabelle e accedere ai dati. Il database archivia due URL per ogni annuncio, uno per l'immagine con dimensioni normali e uno per l'anteprima.
Quando un utente carica un'immagine, il front-end in esecuzione in un ruolo Web archivia l'immagine in un BLOB di Azure, quindi archivia le informazioni sulle inserzioni nel database con un URL che fa riferimento al BLOB e, al tempo stesso, scrive un messaggio in una coda di Azure. Un processo back-end in esecuzione in un ruolo di lavoro esegue periodicamente il polling della coda alla ricerca di nuovi messaggi. Quando compare un nuovo messaggio, il ruolo di lavoro crea un'anteprima per quell'immagine e aggiorna il campo di database relativo all'URL dell'anteprima per quell'inserzione. Il diagramma seguente mostra l'interazione tra le parti dell'applicazione.
Impostazione dell'ambiente di sviluppo
Per iniziare, configurare l'ambiente di sviluppo con Visual Studio e Azure SDK.
Visual Studio 2019 include Azure SDK. Se si usa Visual Studio 2019, non è necessario configurare ulteriormente l'ambiente di sviluppo.
Se si usa Visual Studio 2015, fare clic sul collegamento seguente per installare Azure SDK per Visual Studio 2015.
Se si usa Visual Studio 2013, fare clic sul collegamento seguente per installare Azure SDK per Visual Studio 2013.
Se Visual Studio non è installato, fare clic sul collegamento seguente per installare Visual Studio 2019 con Azure SDK.
Nota
In base al numero di dipendenze da SDK già presenti nel computer, l'installazione dell'SDK può richiedere tempi lunghi, da alcuni minuti ad almeno mezz'ora.
Download ed esecuzione della soluzione completata
Scaricare e decomprimere la soluzione completata.
Avviare Visual Studio.
Scegliere Apri progetto dal menu File, passare alla cartella in cui è stata scaricata la soluzione, quindi aprire il file di soluzione.
Per compilare la soluzione, premere CTRL+MAIUSC+B.
Per impostazione predefinita, Visual Studio ripristina automaticamente il contenuto del pacchetto NuGet, che non era incluso nel file con estensione zip. In caso di mancato ripristino dei pacchetti, installarli manualmente passando alla finestra di dialogo Gestisci pacchetti NuGet per la soluzione, quindi facendo clic sul pulsante Ripristina in alto a destra.
In Esplora soluzioni verificare che come progetto di avvio sia selezionato ContosoAdsCloudService.
Se si usa Visual Studio 2015 o versione successiva, modificare la stringa di connessione di SQL Server nel file Web.config dell'applicazione per il progetto ContosoAdsWeb e nel file ServiceConfiguration.Local.cscfg per il progetto ContosoAdsCloudService. In ogni caso, cambiare "(localdb)\v11.0" in "(localdb)\MSSQLLocalDB".
Premere CTRL+F5 per eseguire l'applicazione.
Quando si esegue localmente un progetto di servizio cloud, Visual Studio richiama automaticamente l'emulatore di calcolo di Azure e l'emulatore di archiviazione di Azure. L'emulatore di calcolo usa le risorse del computer per simulare gli ambienti del ruolo Web e del ruolo di lavoro. L'emulatore di archiviazione usa un database LocalDB di SQL Server Express per simulare la risorsa di archiviazione cloud di Azure.
Alla prima esecuzione di un progetto di servizio cloud, per l'avvio degli emulatori sarà necessario circa un minuto. Dopo l'avvio dell'emulatore, nel browser predefinito verrà visualizzata la home page dell'applicazione.
Selezionare Crea un annuncio.
Immettere alcuni dati di test e selezionare un'immagine jpg da caricare, quindi selezionare Crea.
L'app passa alla pagina Indice, ma non mostra un'anteprima del nuovo annuncio perché l'elaborazione è ancora in corso.
Attendere un attimo, quindi aggiornare la pagina di indice per visualizzare l'anteprima.
Selezionare Dettagli per visualizzare l'immagine a dimensione intera.
L'applicazione è stata eseguita interamente nel computer locale, senza connessione al cloud. L'emulatore di archiviazione archivia i dati di coda e BLOB in un database LocalDB di SQL Server Express e l'applicazione archivia i dati relativi alle inserzioni in un altro database LocalDB. Code First di Entity Framework ha creato automaticamente il database delle inserzioni al primo tentativo di accesso da parte dell'app Web.
Nella sezione seguente la soluzione sarà configurata per usare le risorse cloud di Azure per code, BLOB e per il database dell'applicazione in caso di esecuzione nel cloud. Se si vuole, è possibile continuare l'esecuzione locale usando tuttavia le risorse di archiviazione e database del cloud. È solo una questione di impostazione delle stringhe di connessione, che si vedrà come eseguire.
Distribuire l'applicazione in Azure
Per eseguire l'applicazione nel cloud, eseguire i passaggi seguenti:
- Creare un servizio cloud di Azure.
- Creare un database nel database SQL di Azure.
- Creare un account di archiviazione di Azure.
- Configurare la soluzione per l'uso del database in caso di esecuzione in Azure.
- Configurare la soluzione per l'uso dell'account di archiviazione di Azure in caso di esecuzione in Azure.
- Distribuire il progetto nel servizio cloud di Azure.
Creazione di un servizio cloud di Azure
Un servizio cloud in Azure è l'ambiente in cui sarà eseguita l'applicazione.
Accedere al portale di Azure nel browser.
Selezionare Crea una risorsa > Calcolo > Servizio cloud.
Nella casella di input nome DNS (Domain Name System) immettere un prefisso URL per il servizio cloud.
L'URL deve essere univoco. Se il prefisso scelto è già in uso, verrà visualizzato un messaggio di errore.
Specificare un nuovo gruppo di risorse per il servizio. Selezionare Crea nuovo e quindi digitare un nome nella casella di input Gruppo di risorse, ad esempio CS_contososadsRG.
Scegliere l'area geografica in cui si vuole distribuire l'applicazione.
Questo campo specifica il data center in cui è ospitato il servizio cloud. Per un'applicazione di produzione, scegliere l'area più vicina ai clienti. Per questa esercitazione, scegliere l'area geografica più vicina alla propria ubicazione.
Seleziona Crea.
L'immagine seguente illustra la creazione di un servizio cloud il cui URL è CSvccontosoads.cloudapp.net.
Creare un database nel database SQL di Azure
Quando l'app è in esecuzione nel cloud, userà un database basato sul cloud.
Nel portale di Azure selezionare Crea una risorsa > Database > Database SQL.
Nella casella Nome database immettere contosoads.
In Gruppo di risorse scegliere Usa esistente e selezionare il gruppo di risorse usato per il servizio cloud.
Nella schermata illustrata di seguito selezionare Server - Configurare le impostazioni necessarie e Creare un nuovo server.
In alternativa, se la sottoscrizione è già associata a un server, sarà possibile selezionare quel server dall'elenco a discesa.
Nella casella Nome server immettere csvccontosodbserver.
Immettere un Nome di accesso e una Password per l'amministratore.
Se si seleziona Creare un nuovo server non si immetteranno un nome e una password esistenti in questa casella, ma un nuovo nome e una nuova password definiti in questo momento e da usare in seguito per l'accesso al database. Se è stato selezionato un server creato in precedenza, il portale richiede la password dell'account utente amministratore già creato.
Scegliere la stessa località selezionata per il servizio cloud.
Quando il servizio cloud e il database si trovano in data center diversi (aree diverse), la latenza aumenta e vengono addebitati costi per la larghezza di banda all'esterno del data center. La larghezza di banda nell'ambito di un data center è gratuita.
Selezionare Consenti ai servizi di Azure di accedere al server.
Selezionare Seleziona per il nuovo server.
Scegliere Create (Crea).
Creare un account di archiviazione di Azure
Un account di archiviazione di Azure offre risorse per l'archiviazione di dati di code e BLOB nel cloud.
In un'applicazione effettiva si creano in genere account separati per i dati dell'applicazione rispetto ai dati di registrazione e account separati per i dati di test rispetto ai dati di produzione. In questa esercitazione viene usato un solo account.
Nel portale di Azure selezionare Crea una risorsa > Archiviazione > Account di archiviazione - BLOB, file, tabella, coda.
Nella casella Nome immettere un prefisso URL.
La combinazione di questo prefisso e del testo visualizzato sotto la casella corrisponderà all'URL univoco dell'account di archiviazione. Se il prefisso immesso è già usato da un altro utente, scegliere un prefisso diverso.
Impostare Modello di distribuzione su Classica.
Nell'elenco a discesa Replica scegliere Archiviazione con ridondanza locale.
Quando per un account di archiviazione è abilitata la replica geografica, il contenuto archiviato viene replicato in un data center secondario per permettere il failover in caso di emergenza grave nella posizione primaria. La replica geografica può comportare costi aggiuntivi. Per gli account di test e di sviluppo si preferisce in genere non pagare per la replica geografica. Per altre informazioni, vedere la pagina relativa alla creazione, gestione o eliminazione di un account di archiviazione.
In Gruppo di risorse selezionare Usa esistente e selezionare il gruppo di risorse usato per il servizio cloud.
Scegliere dall'elenco a discesa Località la stessa area geografica selezionata per il servizio cloud.
Quando il servizio cloud e l'account di archiviazione si trovano in data center diversi (aree diverse), la latenza aumenta e vengono applicati addebiti per la larghezza di banda al di fuori del data center. La larghezza di banda nell'ambito di un data center è gratuita.
I gruppi di affinità di Azure offrono un meccanismo per ridurre la distanza tra le risorse in un data center e di conseguenza la latenza. Questa esercitazione non usa gruppi di affinità. Per altre informazioni, vedere Come creare un gruppo di affinità in Azure.
Scegliere Create (Crea).
La seguente figura illustra la creazione di un account di archiviazione con l'URL
csvccontosoads.core.windows.net
.
Configurare la soluzione per l'uso del database nel database SQL di Azure in caso di esecuzione in Azure
Il progetto Web e il progetto ruolo di lavoro dispongono di una stringa di connessione di database specifica e quando l'app è in esecuzione in Azure ogni progetto deve puntare al database nel database SQL di Azure.
Sarà necessario usare una trasformazione Web.config per il ruolo Web e un'impostazione dell'ambiente del servizio cloud per il ruolo di lavoro.
Nota
In questa sezione e nella sezione successiva, le credenziali vengono archiviate in file di progetto. Non archiviare dati sensibili in archivi pubblici di codice sorgente.
Nel progetto ContosoAdsWeb aprire il file di trasformazione Web.Release.config per il file Web.config dell'applicazione, eliminare il blocco di commento che include un elemento
<connectionStrings>
e sostituirlo incollando il codice seguente.<connectionStrings> <add name="ContosoAdsContext" connectionString="{connectionstring}" providerName="System.Data.SqlClient" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/> </connectionStrings>
Lasciare aperto il file per la modifica.
Nel portale di Azure scegliere Database SQL nel riquadro sinistro, selezionare il database creato per l'esercitazione, quindi selezionare Mostra stringhe di connessione.
Il portale visualizza le stringhe di connessione, con un segnaposto per la password.
Nel file di trasformazione Web.Release.config eliminare
{connectionstring}
e incollare al suo posto la stringa di connessione ADO.NET dal portale di Azure.Nella stringa di connessione incollata nel file di trasformazione Web.Release.config sostituire
{your_password_here}
con la password creata per il nuovo database SQL.Salvare il file.
Selezionare e copiare la stringa di connessione, senza le virgolette tra cui è racchiusa, per usarla nei passaggi seguenti per la configurazione del progetto di ruolo di lavoro.
In Esplora soluzioni, in Ruoli nel progetto del servizio cloud fare clic con il pulsante destro del mouse su ContosoAdsWorker, quindi selezionare Proprietà.
Scegliere la scheda Impostazioni .
Impostare Configurazione servizio su Cloud.
Selezionare il campo Valore per l'impostazione
ContosoAdsDbConnectionString
e quindi incollare la stringa di connessione copiata dalla sezione precedente dell'esercitazione.Salva le modifiche.
Configurare la soluzione per l'uso dell'account di archiviazione di Azure in caso di esecuzione in Azure
Le stringhe di connessione per l'account di archiviazione di Azure per il progetto ruolo Web e il progetto ruolo di lavoro sono archiviate nelle impostazioni di ambiente nel progetto di servizio cloud. Per ogni progetto è disponibile un insieme di impostazioni distinto da usare quando l'applicazione viene eseguita localmente e nel cloud. Saranno aggiornate le impostazioni dell'ambiente cloud per i progetti di ruolo di lavoro e Web.
In Esplora soluzioni fare clic con il pulsante destro del mouse su ContosoAdsWeb nella sezione Ruoli del progetto ContosoAdsCloudService, quindi selezionare Proprietà.
Scegliere la scheda Impostazioni . Nella casella di riepilogo Configurazione servizio selezionare Cloud.
Se si seleziona la voce StorageConnectionString, verrà visualizzato un pulsante con puntini di sospensione (...) all'estremità destra della riga. Fare clic su tale pulsante per aprire la finestra di dialogo Crea Stringa di connessione di archiviazione.
Nella finestra di dialogo Crea Stringa di connessione di archiviazione selezionare Sottoscrizione, scegliere l'account di archiviazione creato in precedenza, quindi selezionare OK. Lo strumento di esplorazione richiede le credenziali dell'account Azure se è ancora necessario eseguire l'accesso.
Salva le modifiche.
Eseguire la stessa procedura usata per la stringa di connessione
StorageConnectionString
per impostare la stringa di connessioneMicrosoft.WindowsAzure.Plugins.Diagnostics.ConnectionString
.Questa stringa di connessione è usata per la registrazione.
Eseguire la stessa procedura usata per il ruolo ContosoAdsWeb per impostare entrambe le stringhe di connessione per il ruolo ContosoAdsWorker. Ricordarsi di impostare Configurazione servizio su Cloud.
Le impostazioni dell'ambiente del ruolo configurate tramite l'interfaccia utente di Visual Studio sono archiviate nei seguenti file del progetto ContosoAdsCloudService:
- ServiceDefinition.csdef: definisce i nomi delle impostazioni.
- ServiceConfiguration.Cloud.cscfg: fornisce valori per l'esecuzione dell'app nel cloud.
- ServiceConfiguration.Local.cscfg: fornisce valori per l'esecuzione locale dell'app.
Il file ServiceDefinition.csdef include ad esempio le definizioni seguenti:
<ConfigurationSettings>
<Setting name="StorageConnectionString" />
<Setting name="ContosoAdsDbConnectionString" />
</ConfigurationSettings>
E il file ServiceConfiguration.Cloud.cscfg include i valori immessi per queste impostazioni in 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>
L'impostazione <Instances>
specifica il numero di macchine virtuali in cui Azure eseguirà il codice del ruolo di lavoro. La sezione Passaggi successivi include collegamenti ad altre informazioni sulla scalabilità orizzontale di un servizio cloud,
Distribuire il progetto in Azure
In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto cloud ContosoAdsCloudService, quindi scegliere Pubblica.
Nel passaggio Accedi della procedura guidata Pubblica applicazione Azure selezionare Avanti.
Nel passaggio Impostazioni della procedura guidata, selezionare Avanti.
Le impostazioni predefinite della scheda Advanced sono corrette per questa esercitazione. Per informazioni sulla scheda Avanzate, vedere Procedura guidata Pubblica l'applicazione Azure.
Nel passaggio Riepilogo selezionare Pubblica.
La finestra Log attività di Azure sarà aperta in Visual Studio.
Fare clic sull'icona della freccia verso destra per espandere i dettagli della distribuzione.
Il completamento della distribuzione richiede fino a 5 minuti.
Quando lo stato della distribuzione indica che l'operazione è completata, selezionare l'URL dell'app Web per avviare l'applicazione.
È ora possibile testare l'applicazione creando, visualizzando e modificando alcune inserzioni, esattamente come durante l'esecuzione locale dell'applicazione.
Nota
Al termine dei test, eliminare o arrestare il servizio cloud. Anche se non lo si usa, il servizio cloud accumulerà addebiti, poiché le risorse delle macchine virtuali sono riservate per il servizio. Se lo si lascia in esecuzione, chiunque individui l'URL potrà creare e visualizzare inserzioni. Nel portale di Azure passare alla scheda Panoramica per il servizio cloud, quindi fare clic sul pulsante Elimina nella parte superiore della pagina. Se si vuole semplicemente impedire ad altri utenti di accedere al sito, fare invece clic su Arresta . In questo caso, continueranno a essere generati addebiti. È possibile eseguire una procedura analoga per eliminare il database SQL e l'account di archiviazione quando non sono più necessari.
Creazione di un'applicazione completamente nuova
Se è ancora necessario scaricare l'applicazione completata, eseguire questa operazione. Copiare i file dal progetto scaricato nel nuovo progetto.
Per creare l'applicazione Contoso Ads sono necessari i passaggi seguenti:
- Creare una soluzione servizio cloud di Visual Studio.
- Aggiornare e aggiungere pacchetti NuGet.
- Impostare i riferimenti al progetto.
- Configurare le stringhe di connessione.
- Aggiungere file di codice.
Dopo la creazione della soluzione, esaminare il codice univoco per i progetti di servizio cloud e per i BLOB e le code di Azure.
Creare una soluzione servizio cloud di Visual Studio
In Visual Studio scegliere Nuovo progetto from the File.
Nel riquadro sinistro della finestra di dialogo Nuovo progetto espandere Visual C#, scegliere i modelli Cloud, quindi selezionare il modello Servizio cloud di Azure.
Denominare il progetto e la soluzione ContosoAdsCloudService e quindi selezionare OK.
Nella finestra di dialogo Nuovo servizio cloud Azure aggiungere un ruolo Web e un ruolo di lavoro. Assegnare il nome ContosoAdsWeb al ruolo Web e il nome ContosoAdsWorker al ruolo di lavoro. Usare l'icona a forma di matita nel riquadro di destra per modificare i nomi predefiniti dei ruoli.
Quando appare la finestra di dialogo Nuovo progetto ASP.NET per il ruolo Web, scegliere il modello MVC, quindi selezionare Modifica autenticazione.
Nella finestra di dialogo Modifica autenticazione scegliere Nessuna autenticazione, quindi selezionare OK.
Nella finestra di dialogo Nuovo progetto ASP.NET selezionare OK.
In Esplora soluzioni fare clic con il pulsante destro del mouse sulla soluzione, non su uno dei progetti, quindi scegliere Aggiungi - Nuovo progetto.
Nella finestra di dialogo Aggiungi nuovo progetto scegliere Windows in Visual C# nel riquadro sinistro e quindi selezionare il modello Libreria di classi.
Assegnare il nome ContosoAdsCommonal progetto, quindi selezionare OK.
È necessario che i progetti di ruolo Web e di ruolo di lavoro facciano riferimento al contesto e al modello di dati di Entity Framework. In alternativa, è possibile definire le classi correlate a Entity Framework nel progetto di ruolo Web e fare riferimento a tale progetto dal progetto di ruolo di lavoro. Nell'approccio alternativo, tuttavia, il progetto di ruolo di lavoro includerebbe un riferimento ad assembly Web non necessari.
Aggiornare e aggiungere pacchetti NuGet
Aprire la finestra di dialogo Gestisci pacchetti NuGet per la soluzione.
Nella parte superiore della finestra selezionare Aggiornamenti.
Cercare il pacchetto WindowsAzure.Storage. Se è incluso nell'elenco, selezionarlo e scegliere i progetti Web e di lavoro in cui aggiornarlo e quindi selezionare Aggiorna.
La libreria del client di archiviazione viene aggiornata con frequenza maggiore rispetto ai modelli di progetto di Visual Studio. È quindi possibile che la versione disponibile in un progetto appena creato debba essere aggiornata.
Nella parte superiore della finestra selezionare Sfoglia.
Individuare il pacchetto NuGet EntityFramework e installarlo nei tre progetti.
Trovare il pacchetto NuGet Microsoft.WindowsAzure.ConfigurationManager e installarlo nel progetto del ruolo di lavoro.
Configurare le preferenze del progetto
Nel progetto ContosoAdsWeb configurare un riferimento al progetto ContosoAdsCommon. Fare clic con il pulsante destro del mouse sul progetto ContosoAdsWeb, quindi selezionare Riferimenti - Aggiungi riferimenti. Nella finestra di dialogo Gestione riferimenti, selezionare Soluzione - Progetti nel riquadro sinistro, selezionare ContosoAdsCommon, quindi selezionare OK.
Nel progetto ContosoAdsWorker configurare un riferimento al progetto ContosoAdsCommon.
ContosoAdsCommon contiene il modello di dati e la classe di contesto di Entity Framework, che usa sia il front-end che il back-end.
Nel progetto ContosoAdsWorker configurare un riferimento a
System.Drawing
.Questo assembly è usato dal back-end per convertire le immagini in anteprime.
Configurazione delle stringhe di connessione
In questa sezione verranno configurate le stringhe di connessione di Archiviazione di Azure e SQL per il test in locale. Le istruzioni di distribuzione disponibili in precedenza in questa esercitazione illustrano come configurare le stringhe di connessione per l'esecuzione dell'app nel cloud.
Nel progetto ContosoAdsWeb aprire il file Web.config dell'applicazione e inserire il seguente elemento
connectionStrings
dopo l'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 si usa Visual Studio 2015 o versione successiva, sostituire "v11.0" con "MSSQLLocalDB".
Salva le modifiche.
Nel progetto ContosoAdsCloudService, fare clic con il pulsante destro del mouse su ContosoAdsWeb in Ruoli, quindi selezionare Proprietà.
Nella finestra proprietà di ContosoAdsWeb [Ruolo] selezionare la scheda Impostazioni, quindi selezionare Aggiungi impostazione.
Lasciare l'opzione Configurazione servizio impostata su Tutte le configurazioni.
Aggiungere un'impostazione denominata StorageConnectionString. Impostare il Tipo su ConnectionString, quindi impostare il Valore su UseDevelopmentStorage=true.
Salva le modifiche.
Eseguire la stessa procedura per aggiungere una stringa di connessione di archiviazione nelle proprietà del ruolo ContosoAdsWorker.
Nella finestra Proprietà di ContosoAdsWorker [Ruolo] aggiungere un'altra stringa di connessione:
Nome: ContosoAdsDbConnectionString
Tipo: Stringa
Valore: incollare la stessa stringa di connessione usata per il progetto di ruolo Web. L'esempio seguente si riferisce a Visual Studio 2013, quindi se si copia questo esempio e si usa Visual Studio 2015 o versione successiva è necessario modificare l'origine dati.
Data Source=(localdb)\v11.0; Initial Catalog=ContosoAds; Integrated Security=True; MultipleActiveResultSets=True;
Aggiungere file di codice
In questa sezione, i file di codice saranno copiati dalla soluzione scaricata alla nuova soluzione. Le sezioni seguenti illustrano e spiegano le parti chiave del codice.
Per aggiungere file a un progetto o a una cartella, fare clic con il pulsante destro del mouse sul progetto o sulla cartella, quindi selezionare Aggiungi - Elemento esistente. Selezionare i file desiderati e quindi selezionare Aggiungi. Se viene chiesto se si desidera sostituire i file esistenti, selezionare Sì.
Nel progetto ContosoAdsCommon eliminare il file Class1.cs e sostituirlo con i file Ad.cs e ContosoAdscontext.cs dal progetto scaricato.
Nel progetto ContosoAdsWeb aggiungere i file seguenti dal progetto scaricato.
- Global.asax.cs.
- Nella cartella Views\Shared: _Layout.cshtml.
- Nella cartella Views\Home: Index.cshtml.
- Nella cartella Controllers: AdController.cs.
- Nella cartella Views\Ad (creare prima di tutto la cartella): cinque file .cshtml.
Nel progetto ContosoAdsWorker aggiungere il file WorkerRole.cs dal progetto scaricato.
È ora possibile compilare ed eseguire l'applicazione come indicato in precedenza nell'organizzazione; l'app userà le risorse locali del database e dell'emulatore di archiviazione.
Le sezioni seguenti illustrano il codice correlato all'uso dell'ambiente, dei BLOB e delle code di Azure. Questa esercitazione non spiega come creare controlli e visualizzazioni MVC usando lo scaffolding, come scrivere codice di Entity Framework da usare con database SQL Server oppure le nozioni di base della programmazione asincrona in ASP.NET 4.5. Per informazioni su questi argomenti, vedere le risorse seguenti:
- Introduzione a MVC 5
- Introduzione a EF 6 e MVC 5
- Introduzione alla programmazione asincrona in .NET 4.5.
ContosoAdsCommon - Ad.cs
Il file Ad.cs definisce un'enumerazione per le categorie di inserzione e una classe di entità POCO per le informazioni sulle inserzioni.
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
La classe ContosoAdsContext specifica che la classe Ad è usata in una raccolta DbSet, che sarà archiviata da Entity Framework in un database 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; }
}
La classe ha due costruttori. Il primo è usato dal progetto Web e specifica il nome di una stringa di connessione archiviata nel file Web.config. Il secondo costruttore permette di passare la stringa di connessione effettiva usata dal progetto di ruolo di lavoro, non avendo questo un file Web.config. Si è visto in precedenza dove è stata archiviata questa stringa di connessione. Successivamente, si noterà come il codice recupera la stringa di connessione quando crea un'istanza della classe DbContext.
ContosoAdsWeb - Global.asax.cs
Il codice chiamato dal metodo Application_Start
crea un contenitore BLOB images e una coda images, se non esistono già. Questo codice garantisce che ogni volta che si usa un nuovo account di archiviazione o si usa l'emulatore di archiviazione in un nuovo computer, il codice crea automaticamente il contenitore BLOB e la coda necessari.
Il codice ottiene l'accesso all'account di archiviazione tramite la stringa di connessione del file .cscfg .
var storageAccount = CloudStorageAccount.Parse
(RoleEnvironment.GetConfigurationSettingValue("StorageConnectionString"));
Ottiene quindi un riferimento al contenitore BLOB images , crea il contenitore se non esiste già e configura le autorizzazioni di accesso nel nuovo contenitore. Per impostazione predefinita, i nuovi contenitori permettono l'accesso ai BLOB solo ai client con credenziali dell'account di archiviazione. Per il sito Web è necessario che i BLOB siano pubblici, in modo che sia possibile visualizzare immagini usando gli URL che fanno riferimento ai BLOB delle immagini.
var blobClient = storageAccount.CreateCloudBlobClient();
var imagesBlobContainer = blobClient.GetContainerReference("images");
if (imagesBlobContainer.CreateIfNotExists())
{
imagesBlobContainer.SetPermissions(
new BlobContainerPermissions
{
PublicAccess =BlobContainerPublicAccessType.Blob
});
}
Tramite codice analogo si ottiene un riferimento alla coda images e si crea una nuova coda. In questo caso non sono necessarie modifiche alle autorizzazioni.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
var imagesQueue = queueClient.GetQueueReference("images");
imagesQueue.CreateIfNotExists();
ContosoAdsWeb - _Layout.cshtml
Il file _Layout.cshtml imposta il nome dell'app nell'intestazione e nel piè di pagina e crea una voce di menu "Ads" (Annunci).
ContosoAdsWeb - Views\Home\Index.cshtml
Il file Views\Home\Index.cshtml visualizza i collegamenti di categoria nella home page. I collegamenti passano il valore Integer dell'enumerazione Category
in una variabile querystring alla pagina Ads Index.
<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
Nel file AdController.cs il costruttore chiama il metodo InitializeStorage
per creare oggetti della libreria del client di Archiviazione di Azure che forniscono un'API per l'uso di BLOB e code.
Il codice ottiene quindi un riferimento al contenitore BLOB images, come illustrato in precedenza in Global.asax.cs. Durante questa operazione, imposta un criterio per l'esecuzione di nuovi tentativi predefinito appropriato per un'app Web. Il criterio per l'esecuzione di nuovi tentativi predefinito per il backoff esponenziale potrebbe causare l'interruzione dell'app Web per più di un minuto in caso di nuovi tentativi ripetuti per un errore temporaneo. Il criterio di ripetizione dei tentativi specificato qui attende tre secondi dopo ogni tentativo, fino a un massimo di tre tentativi.
var blobClient = storageAccount.CreateCloudBlobClient();
blobClient.DefaultRequestOptions.RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(3), 3);
imagesBlobContainer = blobClient.GetContainerReference("images");
Tramite codice analogo si ottiene un riferimento alla coda images.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
queueClient.DefaultRequestOptions.RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(3), 3);
imagesQueue = queueClient.GetQueueReference("images");
La maggior parte del codice del controller è tipica per l'uso di un modello di dati Entity Framework con una classe DbContext. Un'eccezione è costituita dal metodo Create
HttpPost che carica un file e lo salva nell'archiviazione BLOB. Lo strumento di associazione di modelli fornisce un oggetto HttpPostedFileBase al metodo.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(
[Bind(Include = "Title,Price,Description,Category,Phone")] Ad ad,
HttpPostedFileBase imageFile)
Se l'utente ha selezionato un file da caricare, il codice carica il file, lo salva in un BLOB e aggiorna il record del database Ad con un URL che fa riferimento al BLOB.
if (imageFile != null && imageFile.ContentLength != 0)
{
blob = await UploadAndSaveBlobAsync(imageFile);
ad.ImageURL = blob.Uri.ToString();
}
Il codice che esegue il caricamento si trova nel metodo UploadAndSaveBlobAsync
. Crea un nome GUID per il BLOB, aggiorna e salva il file, quindi restituisce un riferimento al BLOB salvato.
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;
}
Dopo aver caricato un BLOB e aggiornato il database, il metodo Create
HttpPost crea un messaggio di coda per segnalare al processo back-end che un'immagine è pronta per la conversione in anteprima.
string queueMessageString = ad.AdId.ToString();
var queueMessage = new CloudQueueMessage(queueMessageString);
await queue.AddMessageAsync(queueMessage);
Il codice per il metodo Edit
HttpPost è simile, con la differenza che se l'utente seleziona un nuovo file immagine, sarà necessario eliminare eventuali BLOB già esistenti.
if (imageFile != null && imageFile.ContentLength != 0)
{
await DeleteAdBlobsAsync(ad);
imageBlob = await UploadAndSaveBlobAsync(imageFile);
ad.ImageURL = imageBlob.Uri.ToString();
}
L’esempio successivo riporta il codice per l'eliminazione dei BLOB in caso di eliminazione di un'inserzione.
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
Il file Index.cshtml mostra le anteprime insieme agli altri dati delle inserzioni.
<img src="@Html.Raw(item.ThumbnailURL)" />
Il file Details.cshtml mostra l'immagine con dimensioni normali.
<img src="@Html.Raw(Model.ImageURL)" />
ContosoAdsWeb - Views\Ad\Create.cshtml ed Edit.cshtml
I file Create.cshtml e Edit.cshtml specificano la codifica di moduli che permette al controller di ottenere l'oggetto HttpPostedFileBase
.
@using (Html.BeginForm("Create", "Ad", FormMethod.Post, new { enctype = "multipart/form-data" }))
Un elemento <input>
segnala al browser che è necessario fornire una finestra di selezione del file.
<input type="file" name="imageFile" accept="image/*" class="form-control fileupload" />
ContosoAdsWorker - WorkerRole.cs - Metodo OnStart
L'ambiente del ruolo di lavoro di Azure chiama il metodo OnStart
nella classe WorkerRole
durante la fase di avvio del ruolo di lavoro e chiama il metodo Run
al termine dell'esecuzione del metodo OnStart
.
Il metodo OnStart
ottiene la stringa di connessione del database dal file con estensione cscfg e la passa alla classe DbContext di Entity Framework. Per impostazione predefinita, sarà usato il provider SQLClient. Non è quindi necessario specificare alcun provider.
var dbConnString = CloudConfigurationManager.GetSetting("ContosoAdsDbConnectionString");
db = new ContosoAdsContext(dbConnString);
In seguito, il metodo ottiene un riferimento all'account di archiviazione e crea il contenitore BLOB e la coda, se non esistono già. Il codice da usare è simile a quello già usato per il metodo Application_Start
del ruolo Web.
ContosoAdsWorker - WorkerRole.cs - Metodo Run
Il metodo Run
è chiamato al termine del processo di inizializzazione del metodo OnStart
. Il metodo esegue un ciclo infinito che cerca nuovi messaggi di coda e li elabora quando arrivano.
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);
}
}
}
Dopo ogni iterazione del ciclo, se non sono stati trovati messaggi di coda, il programma rimane inattivo per un secondo. Ciò impedisce al ruolo di lavoro di generare costi eccessivi relativi al tempo della CPU e alle transazioni di archiviazione. Come ricordato da Microsoft Customer Advisory Team, uno sviluppatore aveva scordato di includere questo dettaglio, aveva eseguito la distribuzione in produzione ed era partito per le ferie. Al ritorno, tale la dimenticanza era costata più cara delle vacanze.
A volte il contenuto di un messaggio di coda provoca un errore di elaborazione. Questo messaggio è definito un messaggio non elaborabile. Se è stato appena registrato un errore e il ciclo è stato riavviato, è possibile che venga tentato di elaborare questo messaggio all'infinito. Il blocco CATCH include quindi un'istruzione IF che verifica il numero di volte in cui l'app ha tentato di elaborare il messaggio corrente. Se il numero è superiore a 5, il messaggio sarà eliminato dalla coda.
ProcessQueueMessage
è chiamato quando viene trovato un messaggio della coda.
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);
}
Questo codice legge il database per ottenere l'URL dell'immagine. converte l'immagine in un'anteprima, salva l'anteprima in un BLOB, aggiorna il database con l'URL del BLOB dell'anteprima ed elimina il messaggio in coda.
Nota
Il codice nel metodo ConvertImageToThumbnailJPG
usa le classi disponibili nello spazio dei nomi System.Drawing per maggiore semplicità. Le classi in questo spazio dei nomi, tuttavia, sono state progettate per l'uso con Windows Form. Non sono supportate per l'uso in un servizio Windows o ASP.NET. Per altre informazioni sulle opzioni di elaborazione delle immagini, vedere Generazione dinamica delle immagini e Informazioni dettagliate sul ridimensionamento delle immagini.
Risoluzione dei problemi
In caso di problemi durante l'esecuzione delle istruzioni di questa esercitazione, di seguito sono indicati alcuni errori comuni e le relative soluzioni.
ServiceRuntime.RoleEnvironmentException
L'oggetto RoleEnvironment
è fornito da Azure quando si esegue un'applicazione in Azure o in caso di esecuzione in modalità locale tramite l'emulatore di calcolo di Azure. Se questo errore è visualizzato durante l'esecuzione locale, assicurarsi di avere impostato il progetto ContosoAdsCloudService come progetto di avvio. Con questa impostazione, il progetto sarà configurato per l'esecuzione con l'emulatore di Calcolo di Azure.
L'applicazione usa RoleEnvironment di Azure anche per ottenere i valori delle stringhe di connessione archiviati nei file con estensione cscfg. È quindi possibile che questa eccezione sia generata da una stringa di connessione mancante. Assicurarsi di avere creato l'impostazione StorageConnectionString per entrambe le configurazioni, cloud e locale, nel progetto ContosoAdsWeb e di avere creato entrambe le stringhe di connessione per entrambe le configurazioni nel progetto ContosoAdsWorker. Se si esegue una ricerca di tipo Trova tutto per StorageConnectionString nell'intera soluzione, dovrebbero essere rilevate 9 occorrenze in 6 file.
Non è possibile eseguire l'override sulla porta xxx. Nuova porta con valore inferiore al minimo consentito 8080 per HTTP protocollo
Provare a cambiare il numero di porta usato dal progetto Web. Fare clic con il pulsante destro del mouse sul progetto ContosoAdsWeb, quindi selezionare Proprietà. Fare clic sulla scheda Web, quindi cambiare il numero di porta nell'impostazione URL progetto.
Per un'altra soluzione alternativa che potrebbe risolvere il problema, vedere la sezione successiva.
Altri errori durante l'esecuzione locale
Per impostazione predefinita, i nuovi progetti di servizio cloud usano l'emulatore di calcolo rapido di Azure per simulare l'ambiente di Azure. L'emulatore di Calcolo di Azure è una versione semplificata dell'emulatore di calcolo e in alcuni casi l'emulatore di calcolo completo funzionerà mentre la versione rapida non funzionerà.
Per modificare il progetto in modo che usi l'emulatore completo, fare clic con il pulsante destro del mouse sul progetto ContosoAdsCloudService, quindi selezionare Proprietà. Nella finestra Proprietà selezionare la scheda Web, quindi selezionare il pulsante di opzione Usa emulatore completo.
Per eseguire l'applicazione con l'emulatore completo, sarà necessario aprire Visual Studio con privilegi di amministratore.
Passaggi successivi
L'applicazione Contoso Ads è intenzionalmente semplice, in modo da essere idonea per un'esercitazione introduttiva. Ad esempio, non implementa l'inserimento delle dipendenze o il repository e l'unità dei modelli di lavoro. Non usa un'interfaccia per la registrazione, non usa Migrazioni Code First di Entity Framework per gestire le modifiche del modello di dati o la resilienza della connessione EF per gestire gli errori di rete temporanei e così via.
Per informazioni generali sullo sviluppo per il cloud, vedere l'articolo relativo alla creazione di applicazioni cloud funzionanti con Azure.
Per ulteriori informazioni, vedi le seguenti risorse: