Applicazione ibrida cloud/locale (.NET) usando il servizio d'inoltro WCF di Azure

Introduzione

Questo articolo illustra come compilare un'applicazione cloud ibrida con Microsoft Azure e Visual Studio. Nell'esercitazione si presuppone che l'utente non abbia mai usato Azure. In meno di 30 minuti si otterrà un'applicazione in esecuzione nel cloud e che usa più risorse di Azure.

Si acquisiranno le nozioni seguenti:

  • Creare o adattare un servizio Web esistente utilizzabile in una soluzione Web.
  • Usare il servizio d'inoltro WCF di Azure per condividere dati tra un'applicazione Azure e un servizio Web ospitato altrove.
Nota

Per completare l'esercitazione, è necessario un account Azure. È possibile attivare i benefici della sottoscrizione MSDN o iscriversi per un account gratuito.

Vantaggi del servizio d'inoltro di Azure con soluzioni ibride

Le soluzioni aziendali sono in genere costituite da una combinazione di codice personalizzato appositamente scritto in risposta a specifici requisiti aziendali e da funzionalità esistenti fornite da soluzioni e sistemi già implementati.

Da qualche tempo gli architetti di soluzioni hanno iniziato a usare il cloud per semplificare la gestione dei requisiti di scalabilità e ridurre i costi operativi. Nell'adottare un tale approccio hanno quindi scoperto che le risorse di servizi esistenti che desiderano sfruttare come blocchi predefiniti delle soluzioni si trovano all'interno del firewall aziendale e quindi non sono facilmente raggiungibili dalla soluzione cloud. Molti servizi interni non sono creati né vengono ospitati in modo tale da consentirne una agevole esposizione al perimetro della rete aziendale.

Il servizio d'inoltro di Azure è progettato per i casi d'uso in cui i servizi Web WCF (Windows Communication Foundation) vengono resi accessibili in modo protetto a soluzioni che risiedono all'esterno del perimetro aziendale senza richiedere modifiche di notevole impatto all'infrastruttura di rete aziendale. Tali servizi d'inoltro sono comunque ospitati all'interno dell'ambiente esistente, ma delegano l'ascolto delle sessioni e delle richieste in ingresso al servizio d'inoltro ospitato nel cloud. Il servizio d'inoltro di Azure protegge anche quei servizi dall'accesso non autorizzato tramite l'autenticazione con firma di accesso condiviso.

Scenario della soluzione

In questa esercitazione si creerà un sito Web ASP.NET che consente di visualizzare un elenco di prodotti nella pagina relativa all'inventario dei prodotti.

In questa esercitazione si presuppone che le informazioni sui prodotti siano già disponibili in un sistema locale esistente e che per accedere a tale sistema venga usato il servizio d'inoltro di Azure. Tale operazione viene simulata da un servizio Web eseguito in una semplice applicazione console ed è supportata da un insieme di prodotti in memoria. Sarà quindi possibile eseguire questa applicazione console nel computer in uso e distribuire il ruolo Web in Azure. In tal modo sarà possibile osservare che il ruolo Web in esecuzione nel data center di Azure verrà effettivamente chiamato nel computer in uso, anche se quest'ultimo sarà quasi certamente protetto da almeno un firewall e un livello NAT (Network Address Translation).

Configurare l'ambiente di sviluppo

Prima di iniziare a sviluppare applicazioni Azure, è necessario scaricare gli strumenti e configurare l'ambiente di sviluppo:

  1. Installare Azure SDK per .NET dalla pagina di download di SDK.
  2. Nella colonna .NET fare clic sulla versione di Visual Studio in uso. I passaggi di questa esercitazione usano Visual Studio 2015, ma funzionano anche con Visual Studio 2017.
  3. Quando viene richiesto se eseguire o salvare il file di installazione, fare clic su Esegui.
  4. Nell'Installazione guidata piattaforma Web fare clic su Installa e procedere con l'installazione.
  5. Al termine dell'installazione, saranno disponibili tutti gli strumenti necessari per avviare lo sviluppo dell’app. Nell'SDK sono disponibili gli strumenti che consentono di sviluppare con facilità applicazioni per Azure in Visual Studio.

Creare uno spazio dei nomi

Per usare le funzionalità del servizio d'inoltro di Azure, è prima necessario creare uno spazio dei nomi del servizio. Uno spazio dei nomi funge da contenitore di ambito in cui indirizzare le risorse di Azure nell'applicazione. Seguire queste istruzioni per creare uno spazio dei nomi di inoltro.

Creare un server locale

In primo luogo, si creerà un sistema di catalogo prodotti locale fittizio. Si tratta di un sistema locale abbastanza semplice che intende rappresentare un catalogo prodotti effettivo che include una superficie completa di servizi da integrare.

Il progetto è un'applicazione console di Visual Studio e usa il pacchetto NuGet del bus di servizio di Azure per includere le librerie e le impostazioni di configurazione del bus di servizio.

Creare il progetto

  1. Usando privilegi di amministratore, avviare Microsoft Visual. A tale scopo, fare clic con il tasto destro del mouse sull'icona del programma Visual Studio e quindi fare clic su Esegui come amministratore.
  2. In Visual Studio scegliere Nuovo dal menu File, quindi fare clic su Progetto.
  3. Da Modelli installati in Visual C# fare clic su App console (.NET Framework). Nella casella Nome digitare il nome ProductsServer:

  4. Fare clic su OK per creare il progetto ProductsServer.
  5. Se Gestione pacchetti NuGet per Visual Studio è già stato installato, continuare con il passaggio successivo. In caso contrario, visitare il sito NuGet e fare clic su Install NuGet (Installa NuGet). Seguire le istruzioni visualizzate per installare Gestione pacchetti NuGet, quindi riavviare Visual Studio.
  6. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto ProductsServer e quindi scegliere Gestisci pacchetti NuGet.
  7. Fare clic sulla scheda Sfoglia e quindi cercare Microsoft Azure Service Bus. Selezionare il pacchetto WindowsAzure.ServiceBus.
  8. Fare clic su Installae accettare le condizioni per l'utilizzo.

    I riferimenti agli assembly client necessari sono ora disponibili.

  9. Aggiungere una nuova classe per il contratto dei prodotti. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto ProductsServer, scegliere Aggiungi e quindi fare clic su Classe.
  10. Nella casella Nome digitare il nome ProductsContract.cs. Fare quindi clic su Aggiungi.
  11. In ProductsContract.cs sostituire la definizione dello spazio dei nomi con il codice seguente, che consente di definire il contratto per il servizio.

    namespace ProductsServer
    {
        using System.Collections.Generic;
        using System.Runtime.Serialization;
        using System.ServiceModel;
    
        // Define the data contract for the service
        [DataContract]
        // Declare the serializable properties.
        public class ProductData
        {
            [DataMember]
            public string Id { get; set; }
            [DataMember]
            public string Name { get; set; }
            [DataMember]
            public string Quantity { get; set; }
        }
    
        // Define the service contract.
        [ServiceContract]
        interface IProducts
        {
            [OperationContract]
            IList<ProductData> GetProducts();
    
        }
    
        interface IProductsChannel : IProducts, IClientChannel
        {
        }
    }
    
  12. In Program.cs sostituire la definizione dello spazio dei nomi con il codice seguente, che consente di aggiungere il servizio profili e l'host relativo.

    namespace ProductsServer
    {
        using System;
        using System.Linq;
        using System.Collections.Generic;
        using System.ServiceModel;
    
        // Implement the IProducts interface.
        class ProductsService : IProducts
        {
    
            // Populate array of products for display on website
            ProductData[] products =
                new []
                    {
                        new ProductData{ Id = "1", Name = "Rock",
                                         Quantity = "1"},
                        new ProductData{ Id = "2", Name = "Paper",
                                         Quantity = "3"},
                        new ProductData{ Id = "3", Name = "Scissors",
                                         Quantity = "5"},
                        new ProductData{ Id = "4", Name = "Well",
                                         Quantity = "2500"},
                    };
    
            // Display a message in the service console application
            // when the list of products is retrieved.
            public IList<ProductData> GetProducts()
            {
                Console.WriteLine("GetProducts called.");
                return products;
            }
    
        }
    
        class Program
        {
            // Define the Main() function in the service application.
            static void Main(string[] args)
            {
                var sh = new ServiceHost(typeof(ProductsService));
                sh.Open();
    
                Console.WriteLine("Press ENTER to close");
                Console.ReadLine();
    
                sh.Close();
            }
        }
    }
    
  13. In Esplora soluzioni fare doppio clic sul file App.config per aprirlo nell'editor di Visual Studio. Nella parte inferiore dell'elemento <system.ServiceModel>, ma sempre in <system.ServiceModel>, aggiungere il seguente codice XML. Assicurarsi di sostituire yourServiceNamespace con il nome del proprio spazio dei nomi e yourKey con la chiave di firma di accesso condiviso recuperata in precedenza dal portale:

    <system.serviceModel>
    ...
      <services>
         <service name="ProductsServer.ProductsService">
           <endpoint address="sb://yourServiceNamespace.servicebus.windows.net/products" binding="netTcpRelayBinding" contract="ProductsServer.IProducts" behaviorConfiguration="products"/>
         </service>
      </services>
      <behaviors>
         <endpointBehaviors>
           <behavior name="products">
             <transportClientEndpointBehavior>
                <tokenProvider>
                   <sharedAccessSignature keyName="RootManageSharedAccessKey" key="yourKey" />
                </tokenProvider>
             </transportClientEndpointBehavior>
           </behavior>
         </endpointBehaviors>
      </behaviors>
    </system.serviceModel>
    
  14. Nell'elemento <appSettings>, sempre nel file App.config, sostituire il valore della stringa di connessione con la stringa di connessione ottenuta prima dal portale.

    <appSettings>
       <!-- Service Bus specific app settings for messaging connections -->
       <add key="Microsoft.ServiceBus.ConnectionString"
           value="Endpoint=sb://yourNamespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=yourKey"/>
    </appSettings>
    
  15. Premere CTRL+MAIUSC+B oppure scegliere Compila soluzione dal menu Compila per compilare l'applicazione e verificare la correttezza del lavoro svolto finora.

Creare un'applicazione ASP.NET

In questa sezione si creerà una semplice applicazione ASP.NET per visualizzare i dati recuperati dal servizio dei prodotti.

Creare il progetto

  1. Assicurarsi che Visual Studio sia in esecuzione con privilegi di amministratore.
  2. In Visual Studio scegliere Nuovo dal menu File, quindi fare clic su Progetto.
  3. Da Modelli installati in Visual C# fare clic su Applicazione Web ASP.NET (.NET Framework). Assegnare al progetto il nome ProductsPortal. Fare quindi clic su OK.

  4. Nell'elenco dei modelli ASP.NET nella finestra di dialogo Nuova applicazione Web ASP.NET fare clic su MVC.

  5. Fare clic sul pulsante Modifica autenticazione. Nella finestra di dialogo Modifica autenticazione assicurarsi che sia selezionato Nessuna autenticazione e quindi fare clic su OK. Per questa esercitazione si distribuisce un'app che non richiede l'accesso utente.

  6. Nella finestra di dialogo Nuova applicazione Web ASP.NET fare clic su OK per creare l'app MVC.

  7. A questo punto è necessario configurare le risorse di Azure per una nuova app Web. Seguire i passaggi nella sezione Pubblicazione in Azure di questo articolo. Tornare quindi a questa esercitazione e procedere al passaggio successivo.
  8. In Esplora soluzioni fare clic con il pulsante destro del mouse su Modelli, scegliere Aggiungi e infine fare clic su Classe. Nella casella Nome digitare il nome Product.cs. Fare quindi clic su Aggiungi.

Modificare l'applicazione web

  1. Nel file Product.cs in Visual Studio sostituire la definizione dello spazio dei nomi esistente con il codice seguente.

     // Declare properties for the products inventory.
     namespace ProductsWeb.Models
     {
        public class Product
        {
            public string Id { get; set; }
            public string Name { get; set; }
            public string Quantity { get; set; }
        }
     }
    
  2. In Esplora soluzioni espandere la cartella Controller e quindi fare doppio clic sul file HomeController.cs per aprirlo in Visual Studio.
  3. In HomeController.cs sostituire la definizione dello spazio dei nomi esistente con il codice seguente.

    namespace ProductsWeb.Controllers
    {
        using System.Collections.Generic;
        using System.Web.Mvc;
        using Models;
    
        public class HomeController : Controller
        {
            // Return a view of the products inventory.
            public ActionResult Index(string Identifier, string ProductName)
            {
                var products = new List<Product>
                    {new Product {Id = Identifier, Name = ProductName}};
                return View(products);
            }
         }
    }
    
  4. In Esplora soluzioni espandere la cartella Views\Shared e quindi fare doppio clic su _Layout.cshtml per aprirlo nell'editor di Visual Studio.
  5. Modificare tutte le occorrenze di My ASP.NET Application in LITWARE's Products.
  6. Rimuovere i collegamenti Home, About e Contact. Nell'esempio seguente, eliminare il codice evidenziato.

  7. In Esplora soluzioni espandere la cartella Views\Home e quindi fare doppio clic su Index.cshtml per aprirlo nell'editor di Visual Studio. Sostituire l'intero contenuto del file con il codice seguente.

    @model IEnumerable<ProductsWeb.Models.Product>
    
    @{
             ViewBag.Title = "Index";
    }
    
    <h2>Prod Inventory</h2>
    
    <table>
              <tr>
                  <th>
                      @Html.DisplayNameFor(model => model.Name)
                  </th>
                  <th></th>
                  <th>
                      @Html.DisplayNameFor(model => model.Quantity)
                  </th>
              </tr>
    
    @foreach (var item in Model) {
              <tr>
                  <td>
                      @Html.DisplayFor(modelItem => item.Name)
                  </td>
                  <td>
                      @Html.DisplayFor(modelItem => item.Quantity)
                  </td>
              </tr>
    }
    
    </table>
    
  8. Per verificare la correttezza del lavoro svolto finora, premere CTRL+MAIUSC+B per compilare il progetto.

Eseguire l'app in locale

Eseguire l'applicazione per verificarne il funzionamento.

  1. Assicurarsi che il progetto attivo sia ProductsPortal. Fare clic con il pulsante destro del mouse sul nome del progetto in Esplora soluzioni, quindi scegliere Imposta come progetto di avvio.
  2. In Visual Studio premere F5.
  3. L'applicazione dovrebbe risultare in esecuzione in un browser.

Combinare i diversi componenti

Nel passaggio successivo si collegherà il server dei prodotti locale all'applicazione ASP.NET.

  1. Se non è già aperto, in Visual Studio riaprire il progetto ProductsPortal creato nella sezione Creare un'applicazione ASP.NET.
  2. Analogamente a quanto descritto nella sezione "Creare un server locale", aggiungere il pacchetto NuGet ai riferimenti del progetto. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto ProductsPortal e quindi scegliere Gestisci pacchetti NuGet.
  3. Cercare "Bus di servizio" e selezionare la voce WindowsAzure.ServiceBus . Completare quindi l'installazione e chiudere la finestra di dialogo.
  4. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto ProductsPortal, quindi scegliere Aggiungi e infine Elemento esistente.
  5. Individuare il file ProductsContract.cs nel progetto console ProductsServer. Fare clic per evidenziare ProductsContract.cs. Fare clic sulla freccia rivolta verso il basso accanto ad Aggiungi, quindi fare clic su Aggiungi come collegamento.

  6. Aprire il file HomeController.cs nell'editor di Visual Studio e sostituire la definizione dello spazio dei nomi con il codice seguente. Assicurarsi di sostituire yourServiceNamespace con il nome dello spazio dei nomi servizio e yourKey con la chiave di firma di accesso condiviso. In tal modo il client potrà chiamare il servizio locale e restituire il risultato della chiamata.

    namespace ProductsWeb.Controllers
    {
        using System.Linq;
        using System.ServiceModel;
        using System.Web.Mvc;
        using Microsoft.ServiceBus;
        using Models;
        using ProductsServer;
    
        public class HomeController : Controller
        {
            // Declare the channel factory.
            static ChannelFactory<IProductsChannel> channelFactory;
    
            static HomeController()
            {
                // Create shared access signature token credentials for authentication.
                channelFactory = new ChannelFactory<IProductsChannel>(new NetTcpRelayBinding(),
                    "sb://yourServiceNamespace.servicebus.windows.net/products");
                channelFactory.Endpoint.Behaviors.Add(new TransportClientEndpointBehavior {
                    TokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(
                        "RootManageSharedAccessKey", "yourKey") });
            }
    
            public ActionResult Index()
            {
                using (IProductsChannel channel = channelFactory.CreateChannel())
                {
                    // Return a view of the products inventory.
                    return this.View(from prod in channel.GetProducts()
                                     select
                                         new Product { Id = prod.Id, Name = prod.Name,
                                             Quantity = prod.Quantity });
                }
            }
        }
    }
    
  7. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla soluzione ProductsPortal. Verificare di fare clic con il pulsante destro del mouse sulla soluzione, non sul progetto. Scegliere Aggiungi, quindi fare clic su Progetto esistente.
  8. Individuare il progetto ProductsServer, quindi fare doppio clic sulla soluzione ProductsServer.csproj per aggiungerla.
  9. ProductsServer deve essere in esecuzione per visualizzare i dati in ProductsPortal. In Esplora soluzioni fare clic con il pulsante destro del mouse sulla soluzione ProductsPortal e scegliere Proprietà. Viene visualizzata la finestra di dialogo Pagine delle proprietà.
  10. Sul lato sinistro fare clic su Progetto di avvio. Sul lato destro fare clic su Progetti di avvio multipli. Assicurarsi che ProductsServer e ProductsPortal siano visualizzati in questo ordine e che l'azione Avvia sia impostata per entrambi.

  11. Sempre nella finestra di dialogo Proprietà fare clic su Dipendenze progetto sul lato sinistro.

  12. Nell'elenco Progetti fare clic su ProductsServer. Verificare che ProductsPortal non sia selezionato.
  13. Nell'elenco Progetti fare clic su ProductsPortal. Assicurarsi che ProductsServer sia selezionato.

  14. Fare clic su OK nella finestra di dialogo Pagine delle proprietà.

Eseguire il progetto in locale

Per testare l'applicazione in locale, in Visual Studio premere F5. Il server locale, ProductsServer, verrà avviato per primo, quindi verrà avviata l'applicazione ProductsPortal in una finestra del browser. Questa volta si noterà che nell'inventario dei prodotti sono elencati i dati recuperati dal sistema locale del servizio dei prodotti.

Fare clic su Aggiorna nella pagina ProductsPortal. Ogni volta che si aggiorna la pagina, nell'app server viene visualizzato un messaggio quando si chiama GetProducts() da ProductsServer.

Chiudere entrambe le applicazioni prima di procedere al passaggio successivo.

Distribuire il progetto ProductsPortal in un'app Web di Azure

Nel passaggio successivo si ripubblicherà il front-end ProductsPortal dell'app Web di Azure. Eseguire le operazioni seguenti:

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto ProductsPortal e quindi fare clic su Pubblica. Fare quindi clic su Pubblica nella pagina di pubblicazione.

    Nota

    È possibile che nella finestra del browser venga visualizzato un messaggio di errore quando il progetto Web ProductsPortal viene avviato automaticamente dopo la distribuzione. Si tratta di un comportamento previsto che si verifica perché l'applicazione ProductsServer non è ancora in esecuzione.

  2. Copiare l'URL dell'app Web distribuita, perché sarà necessario nel passaggio successivo. È anche possibile ottenere l'URL dalla finestra Attività del servizio app di Azure in Visual Studio:

  3. Chiudere la finestra del browser per arrestare l'applicazione in esecuzione.

Impostare ProductsPortal come app Web

Prima di eseguire l'applicazione nel cloud è necessario assicurarsi che ProductsPortal venga avviato dall'interno di Visual Studio come app Web.

  1. In Visual Studio fare clic con il pulsante destro del mouse sul progetto ProductsPortal e quindi scegliere Proprietà.
  2. Nella colonna sinistra fare clic su Web.
  3. Nella sezione Azione di avvio fare clic sul pulsante URL di avvio e nella casella di testo immettere l'URL dell'app Web distribuita in precedenza, ad esempio, http://productsportal1234567890.azurewebsites.net/.

  4. Scegliere Salva tutto dal menu File in Visual Studio.

  5. In Visual Studio scegliere Ricompila soluzione dal menu Compila.

Eseguire l'applicazione

  1. Premere F5 per compilare ed eseguire l'applicazione. Il server locale, ovvero l'applicazione console ProductsServer, verrà avviato per primo, quindi verrà avviata l'applicazione ProductsPortal in una finestra del browser, come illustrato nella schermata seguente. Si noterà di nuovo che nell'inventario dei prodotti sono elencati i dati recuperati dal sistema locale del servizio dei prodotti, che vengono visualizzati nell'app Web. Verificare l'URL per assicurarsi che ProductsPortal sia in esecuzione nel cloud come app Web di Azure.

    Importante

    L'applicazione console ProductsServer deve essere in esecuzione e in grado di passare dati all'applicazione ProductsPortal. Se nel browser viene visualizzato un errore, attendere alcuni secondi che ProductsServer venga caricato e visualizzi il messaggio seguente. Fare quindi clic su Aggiorna nel browser.

  2. Nel browser fare clic su Aggiorna nella pagina ProductsPortal. Ogni volta che si aggiorna la pagina, nell'app server viene visualizzato un messaggio quando si chiama GetProducts() da ProductsServer.

Passaggi successivi

Per altre informazioni sul servizio d'inoltro di Azure, vedere le risorse seguenti: