Introducción a Azure Cloud Services y ASP.NETGet started with Azure Cloud Services and ASP.NET

Información generalOverview

En este tutorial se muestra cómo crear una aplicación .NET de múltiples niveles con un front-end ASP.NET MVC e implementarla en un servicio en la nube de Azure.This tutorial shows how to create a multi-tier .NET application with an ASP.NET MVC front-end, and deploy it to an Azure cloud service. La aplicación usa Azure SQL Database, el servicio Azure Blob service y el servicio Azure Queue service.The application uses Azure SQL Database, the Azure Blob service, and the Azure Queue service. Puede descargar el proyecto de Visual Studio desde la Galería de código de MSDN.You can download the Visual Studio project from the MSDN Code Gallery.

En el tutorial se muestra cómo crear y ejecutar la aplicación localmente, cómo implementarla en Azure y ejecutarla en la nube y, por último, cómo crearla desde cero.The tutorial shows you how to build and run the application locally, how to deploy it to Azure and run in the cloud, and how to build it from scratch. Puede comenzar por crearla desde cero y después llevar a cabo los pasos de prueba e implementación si lo prefiere.You can start by building from scratch and then do the test and deploy steps afterward if you prefer.

Aplicación Contoso AdsContoso Ads application

La aplicación es un tablón de anuncios publicitario.The application is an advertising bulletin board. Los usuarios crean un anuncio introduciendo texto y cargando una imagen.Users create an ad by entering text and uploading an image. Pueden ver una lista de anuncios con imágenes en miniatura y ver la imagen a tamaño completo cuando seleccionan un anuncio para ver los detalles.They can see a list of ads with thumbnail images, and they can see the full-size image when they select an ad to see the details.

Ad list

La aplicación usa el patrón de trabajo centrado en colas para descargar el trabajo de uso intensivo de CPU de creación de miniaturas y pasarlo a un proceso back-end.The application uses the queue-centric work pattern to off-load the CPU-intensive work of creating thumbnails to a back-end process.

Arquitectura alternativa: Websites y WebJobsAlternative architecture: Websites and WebJobs

En este tutorial se muestra cómo ejecutar un front-end y un back-end en un servicio en la nube de Azure.This tutorial shows how to run both front-end and back-end in an Azure cloud service. Una alternativa es ejecutar el front-end en un sitio web de Azure y usar la característica WebJobs (actualmente en versión preliminar) para el back-end.An alternative is to run the front-end in an Azure website and use the WebJobs feature (currently in preview) for the back-end. Para ver un tutorial en el que se utiliza WebJobs, consulte Introducción al SDK de Azure WebJobs.For a tutorial that uses WebJobs, see Get Started with the Azure WebJobs SDK. Para obtener información sobre cómo elegir los servicios que mejor se adapten a su escenario, consulte Comparación entre Azure Websites, Cloud Services y Virtual Machines.For information about how to choose the services that best fit your scenario, see Azure Websites, Cloud Services, and virtual machines comparison.

Temas que se abordaránWhat you'll learn

  • Habilitar su equipo para desarrollar contenido de Azure mediante la instalación del SDK de Azure.How to enable your machine for Azure development by installing the Azure SDK.
  • Creación de un proyecto de servicio en la nube de Visual Studio con un rol web de ASP.NET MVC y un rol de trabajoHow to create a Visual Studio cloud service project with an ASP.NET MVC web role and a worker role.
  • Prueba del proyecto de servicio en la nube localmente usando el emulador de almacenamiento de Azure.How to test the cloud service project locally, using the Azure storage emulator.
  • Publicación del proyecto en la nube en un servicio en la nube de Azure y prueba usando una cuenta de almacenamiento de Azure.How to publish the cloud project to an Azure cloud service and test using an Azure storage account.
  • Carga de archivos y almacenamiento de los mismos en Azure Blob service.How to upload files and store them in the Azure Blob service.
  • Uso del servicio Cola de Azure para comunicación entre niveles.How to use the Azure Queue service for communication between tiers.

requisitos previosPrerequisites

En este tutorial se da por supuesto que comprende los conceptos básicos sobre Azure Cloud Services como, por ejemplo, la terminología rol web y rol de trabajo.The tutorial assumes that you understand basic concepts about Azure cloud services such as web role and worker role terminology. También se supone que sabe trabajar con proyectos ASP.NET MVC o Web Forms en Visual Studio.It also assumes that you know how to work with ASP.NET MVC or Web Forms projects in Visual Studio. La aplicación de ejemplo usa MVC, pero la mayoría del tutorial también se aplica a Web Forms.The sample application uses MVC, but most of the tutorial also applies to Web Forms.

Puede ejecutar la aplicación localmente sin una suscripción de Azure, pero necesitará una para implementar la aplicación en la nube.You can run the app locally without an Azure subscription, but you'll need one to deploy the application to the cloud. Si aún no la tiene, puede activar los beneficios de suscripción a MSDN o registrarse para obtener una evaluación gratuita.If you don't have an account, you can activate your MSDN subscriber benefits or sign up for a free trial.

Las instrucciones del tutorial funcionan con cualquiera de los productos siguientes:The tutorial instructions work with either of the following products:

  • Visual Studio 2013Visual Studio 2013
  • Visual Studio 2015Visual Studio 2015
  • Visual Studio 2017Visual Studio 2017

Si no tiene uno de ellos, Visual Studio se puede instalar automáticamente al instalar el SDK de Azure.If you don't have one of these, Visual Studio may be installed automatically when you install the Azure SDK.

Arquitectura de la aplicaciónApplication architecture

La aplicación almacena anuncios en una base de datos SQL, usando Entity Framework Code First para crear las tablas y acceder a los datos.The app stores ads in a SQL database, using Entity Framework Code First to create the tables and access the data. Por cada anuncio, la base de datos almacena dos direcciones URL, una para la imagen a tamaño completo y otra para la miniatura.For each ad, the database stores two URLs, one for the full-size image and one for the thumbnail.

Ad table

Cuando un usuario carga una imagen, el front-end que se ejecuta en un rol web almacena dicha imagen en un blob de Azurey la información del anuncio en la base de datos con una dirección URL que apunta al blob.When a user uploads an image, the front-end running in a web role stores the image in an Azure blob, and it stores the ad information in the database with a URL that points to the blob. Al mismo tiempo, escribe mensaje en una cola de Azure.At the same time, it writes a message to an Azure queue. Un proceso back-end que se ejecuta en un rol de trabajo sondea la cola periódicamente para ver si hay nuevos mensajes.A back-end process running in a worker role periodically polls the queue for new messages. Cuando aparece un nuevo mensaje, el rol de trabajo crea una miniatura para la imagen y actualiza el campo de base de datos de la dirección URL de la miniatura para ese anuncio.When a new message appears, the worker role creates a thumbnail for that image and updates the thumbnail URL database field for that ad. El siguiente diagrama muestra cómo interactúan las partes de la aplicación:The following diagram shows how the parts of the application interact.

Contoso Ads architecture

Configuración del entorno de desarrolloSet up the development environment

Para comenzar, configure su entorno de desarrollo con Visual Studio y Azure SDK.To start, set up your development environment with Visual Studio and the Azure SDK.

  • Visual Studio 2017 incluye Azure SDK.Visual Studio 2017 includes the Azure SDK. Si usa VS2017, no se necesita ninguna configuración adicional para el entorno de desarrollo.If you're using VS2017, no additional setup is needed for the development environment.
  • Para Visual Studio 2015, haga clic en el vínculo siguiente para instalar Azure SDK para Visual Studio 2015.For Visual Studio 2015, click the following link to install the Azure SDK for Visual Studio 2015.
  • Para Visual Studio 2013, haga clic en el vínculo siguiente para instalar Azure SDK para Visual Studio 2013.For Visual Studio 2013, click the following link to install the Azure SDK for Visual Studio 2013.

  • Si no tiene instalado Visual Studio, utilice lo siguiente para instalar Visual Studio 2017 con Azure SDK.If you don't have Visual Studio installed, use the following to install Visual Studio 2017 with the Azure SDK.

Nota

Según el número de dependencias de SDK que tenga ya en la máquina, la instalación del SDK puede tardar tiempo, desde unos minutos a media hora o más.Depending on the number of the SDK dependencies already on your machine, installing the SDK could take a long time, from several minutes to a half hour or more.

Descarga y ejecución de la solución completaDownload and run the completed solution

  1. Descargue y descomprima la solución completa.Download and unzip the completed solution.
  2. Inicie Visual Studio.Start Visual Studio.
  3. En el menú Archivo, seleccione Abrir proyecto, vaya a la ubicación donde descargó la solución y abra el archivo de la solución.From the File menu choose Open Project, navigate to where you downloaded the solution, and then open the solution file.
  4. Presione CTRL+MAYÚS+B para compilar la solución.Press CTRL+SHIFT+B to build the solution.

    De forma predeterminada, Visual Studio restaura automáticamente el contenido del paquete NuGet, que no se incluyó en el archivo .zip .By default, Visual Studio automatically restores the NuGet package content, which was not included in the .zip file. Si los paquetes no se restauran, para instalarlos manualmente, vaya al cuadro de diálogo Administrar paquetes NuGet para la solución y haga clic en el botón Restaurar en la parte superior derecha.If the packages don't restore, install them manually by going to the Manage NuGet Packages for Solution dialog box and clicking the Restore button at the top right.

  5. En el Explorador de soluciones, asegúrese de que ContosoAdsCloudService se encuentra seleccionado como proyecto de inicio.In Solution Explorer, make sure that ContosoAdsCloudService is selected as the startup project.
  6. Si va a usar Visual Studio 2015 o una versión superior, cambie la cadena de conexión del servidor SQL Server en el archivo Web.config del proyecto ContosoAdsWeb y en el archivo ServiceConfiguration.Local.cscfg del proyecto ContosoAdsCloudService.If you're using Visual Studio 2015 or higher, change the SQL Server connection string in the application Web.config file of the ContosoAdsWeb project and in the ServiceConfiguration.Local.cscfg file of the ContosoAdsCloudService project. En cada caso, cambie "(localdb) \v11.0" por "(localdb) \MSSQLLocalDB".In each case, change "(localdb)\v11.0" to "(localdb)\MSSQLLocalDB".
  7. Presione CTRL+F5 para ejecutar la aplicación.Press CTRL+F5 to run the application.

    Cuando ejecuta un proyecto de servicio en la nube localmente, Visual Studio invoca automáticamente al emulador de proceso y al emulador de almacenamiento, ambos de Azure.When you run a cloud service project locally, Visual Studio automatically invokes the Azure compute emulator and Azure storage emulator. El emulador de proceso usa los recursos del equipo para simular los entornos de los roles web y de trabajo.The compute emulator uses your computer's resources to simulate the web role and worker role environments. El emulador de almacenamiento usa una base de datos LocalDB de SQL Server Express para simular el almacenamiento en la nube de Azure.The storage emulator uses a SQL Server Express LocalDB database to simulate Azure cloud storage.

    La primera vez que ejecuta un proyecto de servicio en la nube, los emuladores tardan alrededor de un minuto en iniciarse.The first time you run a cloud service project, it takes a minute or so for the emulators to start up. Cuando el inicio del emulador finaliza, se abre el explorador predeterminado en la página de inicio de la aplicación.When emulator startup is finished, the default browser opens to the application home page.

    Contoso Ads architecture

  8. Haga clic en Crear un anuncio.Click Create an Ad.
  9. Escriba algunos datos de prueba y seleccione una imagen .jpg para cargar; a continuación, haga clic en Crear.Enter some test data and select a .jpg image to upload, and then click Create.

    Create page

    La aplicación irá a la página Index, pero no mostrará una miniatura para el nuevo anuncio porque ese procesamiento todavía no se ha llevado a cabo.The app goes to the Index page, but it doesn't show a thumbnail for the new ad because that processing hasn't happened yet.

  10. Espere un momento y actualice la página Index para ver la miniatura.Wait a moment and then refresh the Index page to see the thumbnail.

    Página de índice

  11. Haga clic en el vínculo Detalles correspondiente a su anuncio para ver la imagen a tamaño completo.Click Details for your ad to see the full-size image.

    Details page

Ha estado ejecutando la aplicación completamente en su equipo local, sin conexión a la nube.You've been running the application entirely on your local computer, with no connection to the cloud. El emulador de almacenamiento almacena los datos de cola y de blob en una base de datos LocalDB de SQL Server Express y la aplicación hace lo propio con los datos del anuncio almacenándolos en otra base de datos LocalDB.The storage emulator stores the queue and blob data in a SQL Server Express LocalDB database, and the application stores the ad data in another LocalDB database. Entity Framework Code First creó automáticamente la base de datos de anuncios la primera vez que la aplicación web intentó acceder a ella.Entity Framework Code First automatically created the ad database the first time the web app tried to access it.

En la siguiente sección configurará la solución para usar recursos en la nube de Azure para colas, blobs y la base de datos de aplicación cuando se ejecuta en la nube.In the following section you'll configure the solution to use Azure cloud resources for queues, blobs, and the application database when it runs in the cloud. Podría hacer esto si quisiera seguir trabajando localmente, pero usar recursos de almacenamiento de nube y base de datos.If you wanted to continue to run locally but use cloud storage and database resources, you could do that. Es simplemente una cuestión de configurar las cadenas de conexión, que ahora verá cómo hacerlo.It's just a matter of setting connection strings, which you'll see how to do.

Implementación de la aplicación en AzureDeploy the application to Azure

Llevará a cabo los pasos siguientes para ejecutar la aplicación en la nube:You'll do the following steps to run the application in the cloud:

  • Cree un servicio en la nube de Azure.Create an Azure cloud service.
  • Cree una base de datos SQL de Azure.Create an Azure SQL database.
  • Cree una cuenta de Azure Storage.Create an Azure storage account.
  • Configure la solución para usar la base de datos SQL de Azure cuando se ejecuta en Azure.Configure the solution to use your Azure SQL database when it runs in Azure.
  • Configure la solución para usar la cuenta de almacenamiento de Azure cuando se ejecuta en Azure.Configure the solution to use your Azure storage account when it runs in Azure.
  • Implementar el proyecto en su servicio en la nube de Azure.Deploy the project to your Azure cloud service.

Crear un servicio en la nube de AzureCreate an Azure cloud service

Un servicio en la nube de Azure es el entorno en el que se ejecutará la aplicación.An Azure cloud service is the environment the application will run in.

  1. En el explorador, abra Azure Portal.In your browser, open the Azure portal.
  2. Haga clic en Crear un recurso > Proceso > Servicio en la nube.Click Create a resource > Compute > Cloud Service.

  3. En el cuadro de entrada de nombres DNS, especifique un prefijo de dirección URL para el servicio en la nube.In the DNS name input box, enter a URL prefix for the cloud service.

    Esta dirección URL tiene que ser única.This URL has to be unique. Se mostrará un mensaje de error si el prefijo que elige ya está en uso.You'll get an error message if the prefix you choose is already in use.

  4. Especifique un nuevo grupo de recursos para el servicio.Specify a new Resource group for the service. Haga clic en Crear nuevo y luego escriba un nombre en el cuadro de entrada del grupo de recursos, por ejemplo, CS_contososadsRG.Click Create new and then type a name in the Resource group input box, such as CS_contososadsRG.

  5. Elija la región en la que desea implementar la aplicación.Choose the region where you want to deploy the application.

    Este campo especifica el centro de datos en el que se hospedará el servicio en la nube.This field specifies which datacenter your cloud service will be hosted in. Para una aplicación de producción, elegiría la región más cercana a sus clientes.For a production application, you'd choose the region closest to your customers. Para este tutorial, elija la región más cercana a usted.For this tutorial, choose the region closest to you.

  6. Haga clic en Create(Crear).Click Create.

    En la siguiente imagen, se crea un servicio en la nube con la dirección URL CSvccontosoads.cloudapp.net.In the following image, a cloud service is created with the URL CSvccontosoads.cloudapp.net.

    New Cloud Service

Crear una base de datos SQL de AzureCreate an Azure SQL database

Cuando la aplicación se ejecute en la nube, usará una base de datos basada en la nube.When the app runs in the cloud, it will use a cloud-based database.

  1. En Azure Portal, haga clic en Crear un recurso > Bases de datos > SQL Database.In the Azure portal, click Create a resource > Databases > SQL Database.
  2. En el cuadro Nombre de base de datos , escriba contosoads.In the Database Name box, enter contosoads.
  3. En Grupo de recursos, haga clic en Usar existente y seleccione el grupo de recursos usado para el servicio en la nube.In the Resource group, click Use existing and select the resource group used for the cloud service.
  4. En la imagen siguiente, haga clic en Servidor - Definir la configuración necesaria y Crear un servidor nuevo.In the following image, click Server - Configure required settings and Create a new server.

    Túnel al servidor de base de datos

    Asimismo, si su suscripción ya tiene un servidor, puede seleccionarlo en la lista desplegable.Alternatively, if your subscription already has a server, you can select that server from the drop-down list.

  5. En el cuadro Nombre del servidor, escriba csvccontosodbserver.In the Server name box, enter csvccontosodbserver.

  6. Complete los campos Nombre de inicio de sesión y Contraseña con los datos de un administrador.Enter an administrator Login Name and Password.

    Si seleccionó Crear un servidor nuevo, no escribirá aquí un nombre y una contraseña existentes.If you selected Create a new server, you aren't entering an existing name and password here. Escribirá un nombre y una contraseña nuevos que definirá ahora para usarlos más adelante cuando acceda a la base de datos.You're entering a new name and password that you're defining now to use later when you access the database. Si seleccionó un servidor creado anteriormente, se le pedirá la contraseña de la cuenta de usuario administrativa que ya creó.If you selected a server that you created previously, you'll be prompted for the password to the administrative user account you already created.

  7. Elija la misma ubicación que eligió para el servicio en la nube.Choose the same Location that you chose for the cloud service.

    Cuando el servicio en la nube y la base de datos se encuentren en centros de datos diferentes (distintas regiones), la latencia aumentará y se le cobrará el ancho de banda no perteneciente al centro de datos.When the cloud service and database are in different datacenters (different regions), latency will increase and you will be charged for bandwidth outside the data center. El ancho de banda del centro de datos es gratuito.Bandwidth within a data center is free.

  8. Marque la opción Permitir que los servicios de Azure accedan al servidor.Check Allow azure services to access server.
  9. Haga clic en Seleccionar para el nuevo servidor.Click Select for the new server.

    Nuevo servidor de SQL Database

  10. Haga clic en Create(Crear).Click Create.

Creación de una cuenta de Azure StorageCreate an Azure storage account

Una cuenta de almacenamiento de Azure proporciona recursos para almacenar datos de cola y blob en la nube.An Azure storage account provides resources for storing queue and blob data in the cloud.

En una aplicación real, normalmente crearía cuentas independientes para los datos de aplicación frente a los datos de registro, y cuentas diferentes para datos de prueba frente a datos de producción.In a real-world application, you would typically create separate accounts for application data versus logging data, and separate accounts for test data versus production data. En este tutorial, usará solamente una cuenta.For this tutorial, you'll use just one account.

  1. En Azure Portal, haga clic en Crear un recurso > Almacenamiento > Cuenta de Storage - blob, archivo, tabla, cola.In the Azure portal, click Create a resource > Storage > Storage account - blob, file, table, queue.
  2. En el cuadro Nombre, escriba un prefijo de dirección URL.In the Name box, enter a URL prefix.

    Este prefijo y el texto que verá debajo de la casilla formarán la dirección URL exclusiva para la cuenta de almacenamiento.This prefix plus the text you see under the box will be the unique URL to your storage account. Si el prefijo escrito ya lo usa otra persona, tendrá que elegir un prefijo diferente.If the prefix you enter has already been used by someone else, you'll have to choose a different prefix.

  3. Establezca Modelo de implementación en Clásica.Set the Deployment model to Classic.

  4. Establezca la lista desplegable Replicación en Almacenamiento con redundancia local.Set the Replication drop-down list to Locally redundant storage.

    Cuando se habilita la replicación geográfica para una cuenta de almacenamiento, el contenido almacenado se replica en un centro de datos secundario para permitir la conmutación por error en caso de que se produzca un desastre importante en la ubicación principal.When geo-replication is enabled for a storage account, the stored content is replicated to a secondary datacenter to enable failover if a major disaster occurs in the primary location. La replicación geográfica puede suponer costes adicionales.Geo-replication can incur additional costs. Lo normal es que no quiera pagar por el servicio de replicación geográfica para las cuentas de prueba y desarrollo.For test and development accounts, you generally don't want to pay for geo-replication. Para obtener más información, consulte Creación, administración o eliminación de una cuenta de almacenamiento.For more information, see Create, manage, or delete a storage account.

  5. En Grupo de recursos, haga clic en Usar existente y seleccione el grupo de recursos usado para el servicio en la nube.In the Resource group, click Use existing and select the resource group used for the cloud service.

  6. Establezca la lista desplegable Ubicación en la misma región que eligió para el servicio en la nube.Set the Location drop-down list to the same region you chose for the cloud service.

    Cuando la cuenta de almacenamiento y el servicio en la nube se encuentren en centros de datos diferentes (distintas regiones), la latencia aumentará y se le cobrará el ancho de banda no perteneciente al centro de datos.When the cloud service and storage account are in different datacenters (different regions), latency will increase and you will be charged for bandwidth outside the data center. El ancho de banda del centro de datos es gratuito.Bandwidth within a data center is free.

    Los grupos de afinidad de Azure proporcionan un mecanismo para minimizar la distancia entre los recursos de un centro de datos, lo que puede reducir la latencia.Azure affinity groups provide a mechanism to minimize the distance between resources in a data center, which can reduce latency. Este tutorial no usa grupos de afinidad.This tutorial does not use affinity groups. Para obtener información, consulte Creación de un grupo de afinidad en Azure.For more information, see How to Create an Affinity Group in Azure.

  7. Haga clic en Create(Crear).Click Create.

    New storage account

    En la imagen, se crea una cuenta de almacenamiento con la dirección URL csvccontosoads.core.windows.net.In the image, a storage account is created with the URL csvccontosoads.core.windows.net.

Configurar la solución para usar la base de datos SQL de Azure cuando se ejecuta en AzureConfigure the solution to use your Azure SQL database when it runs in Azure

El proyecto web y el proyecto de rol de trabajo tienen cada uno su propia cadena de conexión de base de datos y cada uno necesita apuntar a la base de datos SQL de Azure cuando la aplicación se ejecuta en Azure.The web project and the worker role project each has its own database connection string, and each needs to point to the Azure SQL database when the app runs in Azure.

Usará una transformación Web.config para el rol web y una configuración de entorno de servicio en la nube para el rol de trabajo.You'll use a Web.config transform for the web role and a cloud service environment setting for the worker role.

Nota

En esta sección y en la siguiente almacenará credenciales en archivos de proyecto.In this section and the next section, you store credentials in project files. No almacene información confidencial en repositorios de código fuente público.Don't store sensitive data in public source code repositories.

  1. En el proyecto ContosoAdsWeb, abra el archivo de transformación Web.Release.config del archivo Web.config de la aplicación, elimine el bloque de comentario que contiene un elemento <connectionStrings> y pegue el siguiente código en su lugar.In the ContosoAdsWeb project, open the Web.Release.config transform file for the application Web.config file, delete the comment block that contains a <connectionStrings> element, and paste the following code in its place.

    <connectionStrings>
        <add name="ContosoAdsContext" connectionString="{connectionstring}"
        providerName="System.Data.SqlClient" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
    </connectionStrings>
    

    Deje el archivo abierto para editarlo.Leave the file open for editing.

  2. En Azure Portal, haga clic en SQL Database en el panel izquierdo, haga clic en la base de datos que creó en este tutorial y luego haga clic en Mostrar cadenas de conexión.In the Azure portal, click SQL Databases in the left pane, click the database you created for this tutorial, and then click Show connection strings.

    Mostrar cadenas de conexión

    El portal muestra las cadenas de conexión con un marcador de posición para la contraseña.The portal displays connection strings, with a placeholder for the password.

    Cadenas de conexión

  3. En el archivo de transformación Web.Release.config, elimine {connectionstring} y pegue en su lugar la cadena de conexión ADO.NET de Azure Portal.In the Web.Release.config transform file, delete {connectionstring} and paste in its place the ADO.NET connection string from the Azure portal.
  4. En la cadena de conexión que pegó en el archivo de transformación Web.Release.config, reemplace {your_password_here} por la contraseña creada para la nueva base de datos SQL.In the connection string that you pasted into the Web.Release.config transform file, replace {your_password_here} with the password you created for the new SQL database.
  5. Guarde el archivo.Save the file.
  6. Seleccione una copia de la cadena de conexión (sin las comillas circundantes) para usar en los pasos siguientes para configurar el proyecto de rol de trabajo.Select and copy the connection string (without the surrounding quotation marks) for use in the following steps for configuring the worker role project.
  7. En el Explorador de soluciones, bajo Roles en el proyecto de servicio en la nube, haga clic con el botón derecho en ContosoAdsWorker y, por último, haga clic en Propiedades.In Solution Explorer, under Roles in the cloud service project, right-click ContosoAdsWorker and then click Properties.

    Role properties

  8. Haga clic en la pestaña Configuración .Click the Settings tab.
  9. Cambie Configuración del servicio a Nube.Change Service Configuration to Cloud.
  10. Seleccione el campo Valor de la configuración de ContosoAdsDbConnectionString y pegue la cadena de conexión que copió de la sección anterior del tutorial.Select the Value field for the ContosoAdsDbConnectionString setting, and then paste the connection string that you copied from the previous section of the tutorial.

    Database connection string for worker role

  11. Guarde los cambios.Save your changes.

Configurar la solución para usar la cuenta de almacenamiento de Azure cuando se ejecuta en AzureConfigure the solution to use your Azure storage account when it runs in Azure

Las cadenas de conexión de la cuenta de almacenamiento de Azure tanto para el proyecto de rol web como para el proyecto de rol de trabajo, se almacenan en la configuración del entorno en el proyecto de servicio en la nube.Azure storage account connection strings for both the web role project and the worker role project are stored in environment settings in the cloud service project. Para cada proyecto existe un conjunto independiente de configuraciones para usar cuando la aplicación se ejecuta localmente y cuando se ejecuta en la nube.For each project, there is a separate set of settings to be used when the application runs locally and when it runs in the cloud. Actualizará la configuración del entorno en la nube tanto para proyectos de rol web como para proyectos de rol de trabajo.You'll update the cloud environment settings for both web and worker role projects.

  1. En el Explorador de soluciones, haga clic con el botón derecho en ContosoAdsWeb debajo de Roles en el proyecto ContosoAdsCloudService y después haga clic en Propiedades.In Solution Explorer, right-click ContosoAdsWeb under Roles in the ContosoAdsCloudService project, and then click Properties.

    Role properties

  2. Haga clic en la pestaña Configuración . En el cuadro desplegable Configuración del servicio, seleccione Nube.Click the Settings tab. In the Service Configuration drop-down box, choose Cloud.

    Cloud configuration

  3. Seleccione la entrada StorageConnectionString y verá un botón con unos puntos suspensivos (...) al final de la línea.Select the StorageConnectionString entry, and you'll see an ellipsis (...) button at the right end of the line. Haga clic en el botón de puntos suspensivos para abrir el cuadro de diálogo Crear cadena de conexión de cuenta de almacenamiento .Click the ellipsis button to open the Create Storage Account Connection String dialog box.

    Open Connection String Create box

  4. En el cuadro de diálogo Crear cadena de conexión de almacenamiento, haga clic en Su suscripción, elija la cuenta de almacenamiento que creó antes y haga clic en Aceptar.In the Create Storage Connection String dialog box, click Your subscription, choose the storage account that you created earlier, and then click OK. Si no ha iniciado sesión, se le pedirán las credenciales de la cuenta de Azure.If you're not already logged in, you'll be prompted for your Azure account credentials.

    Create Storage Connection String

  5. Guarde los cambios.Save your changes.
  6. Siga el mismo procedimiento que usó para la cadena de conexión StorageConnectionString para establecer la cadena de conexión Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString.Follow the same procedure that you used for the StorageConnectionString connection string to set the Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString connection string.

    Esta cadena de conexión se usa para registro.This connection string is used for logging.

  7. Siga el mismo procedimiento que usó para el rol ContosoAdsWeb para establecer ambas cadenas de conexión para el rol ContosoAdsWorker.Follow the same procedure that you used for the ContosoAdsWeb role to set both connection strings for the ContosoAdsWorker role. No olvide establecer Configuración del servicio en Nube.Don't forget to set Service Configuration to Cloud.

La configuración del entorno del rol que ha configurado usando la interfaz de usuario de Visual Studio se almacena en los siguientes archivos en el proyecto ContosoAdsCloudService:The role environment settings that you have configured using the Visual Studio UI are stored in the following files in the ContosoAdsCloudService project:

  • ServiceDefinition.csdef : define los nombres de los valores.ServiceDefinition.csdef - Defines the setting names.
  • ServiceConfiguration.Cloud.cscfg : proporciona valores para cuando la aplicación se ejecuta en la nube.ServiceConfiguration.Cloud.cscfg - Provides values for when the app runs in the cloud.
  • ServiceConfiguration.Local.cscfg : proporciona valores para cuando la aplicación se ejecuta localmente.ServiceConfiguration.Local.cscfg - Provides values for when the app runs locally.

Por ejemplo, el archivo ServiceDefinition.csdef incluye las siguientes definiciones:For example, the ServiceDefinition.csdef includes the following definitions:

<ConfigurationSettings>
    <Setting name="StorageConnectionString" />
    <Setting name="ContosoAdsDbConnectionString" />
</ConfigurationSettings>

Y el archivo ServiceConfiguration.Cloud.cscfg incluye los valores introducidos para esas configuraciones en Visual Studio.And the ServiceConfiguration.Cloud.cscfg file includes the values you entered for those settings 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>

La opción <Instances> especifica el número de máquinas virtuales en las que Azure ejecutará el código del rol de trabajo.The <Instances> setting specifies the number of virtual machines that Azure will run the worker role code on. La sección Pasos siguientes incluye vínculos a más información sobre el escalado horizontal a un servicio en la nubeThe Next steps section includes links to more information about scaling out a cloud service,

Implementar el proyecto en AzureDeploy the project to Azure

  1. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto en la nube ContosoAdsCloudService y después seleccione Publicar.In Solution Explorer, right-click the ContosoAdsCloudService cloud project and then select Publish.

    Publish menu

  2. En el paso Iniciar sesión del asistente Publicar aplicación de Azure, haga clic en Siguiente.In the Sign in step of the Publish Azure Application wizard, click Next.

    Sign in step

  3. En el paso Configuración del asistente, haga clic en Siguiente.In the Settings step of the wizard, click Next.

    Settings step

    La configuración predeterminada de la pestaña Avanzada es correcta para este tutorial.The default settings in the Advanced tab are fine for this tutorial. Para obtener más información sobre la pestaña de opciones avanzadas, consulte Asistente para publicar aplicación de Azure.For information about the advanced tab, see Publish Azure Application Wizard.

  4. En el paso Resumen, haga clic en Publicar.In the Summary step, click Publish.

    Summary step

    Se abrirá la ventana Registro de actividad de Azure en Visual Studio.The Azure Activity Log window opens in Visual Studio.

  5. Haga clic en el icono de la flecha derecha para expandir la información de implementación.Click the right arrow icon to expand the deployment details.

    La implementación puede tardar 5 minutos o más en completarse.The deployment can take up to 5 minutes or more to complete.

    Azure Activity Log window

  6. Cuando se haya completado la implementación, haga clic en URL de aplicación web para iniciar la aplicación.When the deployment status is complete, click the Web app URL to start the application.
  7. Ahora puede probar la aplicación creando, viendo y editando algunos anuncios, tal y como hizo cuando ejecutó la aplicación localmente.You can now test the app by creating, viewing, and editing some ads, as you did when you ran the application locally.

Nota

Cuando termine la prueba, elimine o detenga el servicio en la nube.When you're finished testing, delete or stop the cloud service. Aunque no utilice el servicio en la nube, se acumularán cargos porque se reservan recursos de máquina virtual para él.Even if you're not using the cloud service, it's accruing charges because virtual machine resources are reserved for it. Y si lo deja ejecutando, cualquiera que encuentre su dirección URL puede crear y ver anuncios.And if you leave it running, anyone who finds your URL can create and view ads. En Azure Portal, vaya a la pestaña Información general del servicio en la nube y luego haga clic en el botón Eliminar en la parte superior de la página.In the Azure portal, go to the Overview tab for your cloud service, and then click the Delete button at the top of the page. Si lo que desea es evitar temporalmente que otros accedan al sitio, haga clic en Detener .If you just want to temporarily prevent others from accessing the site, click Stop instead. En ese caso, los cargos seguirán acumulándose.In that case, charges will continue to accrue. Puede seguir un procedimiento similar para eliminar la base de datos SQL y la cuenta de almacenamiento cuando ya no las necesite.You can follow a similar procedure to delete the SQL database and storage account when you no longer need them.

Creación de la aplicación desde ceroCreate the application from scratch

Si todavía no ha descargado la aplicación completada, hágalo ahora.If you haven't already downloaded the completed application, do that now. Copiará los archivos desde el proyecto descargado en el nuevo proyecto.You'll copy files from the downloaded project into the new project.

Para crear la aplicación Contoso Ads es necesario llevar a cabo los pasos siguientes:Creating the Contoso Ads application involves the following steps:

  • Crear una solución de Visual Studio para un servicio en la nube.Create a cloud service Visual Studio solution.
  • Actualizar y agregar paquetes de NuGet.Update and add NuGet packages.
  • Establecer preferencias del proyecto.Set project references.
  • Configurar cadenas de conexión.Configure connection strings.
  • Agregar archivos de código.Add code files.

Una vez creada la solución, se asegurará de que el código es único en proyectos de servicios en la nube y blobs y colas de Azure.After the solution is created, you'll review the code that is unique to cloud service projects and Azure blobs and queues.

Crear una solución de Visual Studio para un servicio en la nubeCreate a cloud service Visual Studio solution

  1. En Visual Studio, elija Nuevo proyecto from the Archivo .In Visual Studio, choose New Project from the File menu.
  2. En el panel de la izquierda del cuadro de diálogo Nuevo proyecto, expanda Visual C#, elija las plantillas Nube y, por último, elija la plantilla Servicio de nube de Azure.In the left pane of the New Project dialog box, expand Visual C# and choose Cloud templates, and then choose the Azure Cloud Service template.
  3. Asigne un nombre al proyecto y a la solución ContosoAdsCloudService y haga clic en Aceptar.Name the project and solution ContosoAdsCloudService, and then click OK.

    Nuevo proyecto

  4. En el cuadro de diálogo Nuevo servicio en la nube de Azure , agregue un rol web o de trabajo.In the New Azure Cloud Service dialog box, add a web role and a worker role. Asigne un nombre al rol web ContosoAdsWeb y al rol de trabajo ContosoAdsWorker.Name the web role ContosoAdsWeb, and name the worker role ContosoAdsWorker. (Use el icono del lápiz situado en el panel derecho para cambiar los nombres predeterminados de los roles.)(Use the pencil icon in the right-hand pane to change the default names of the roles.)

    New Cloud Service Project

  5. Cuando use el cuadro de diálogo Nuevo proyecto ASP.NET para el rol web, elija la plantilla MVC y haga clic en Cambiar autenticación.When you see the New ASP.NET Project dialog box for the web role, choose the MVC template, and then click Change Authentication.

    Cambiar autenticación

  6. En el cuadro de diálogo Cambiar autenticación, elija Sin autenticación y haga clic en Aceptar.In the Change Authentication dialog box, choose No Authentication, and then click OK.

    Sin autenticación

  7. En el cuadro de diálogo Nuevo proyecto ASP.NET, haga clic en Aceptar.In the New ASP.NET Project dialog, click OK.
  8. En el Explorador de soluciones, haga clic con el botón derecho en la solución (no en uno de los proyectos) y elija Agregar - Nuevo proyecto.In Solution Explorer, right-click the solution (not one of the projects), and choose Add - New Project.
  9. En el cuadro de diálogo Agregar nuevo proyecto, elija Windows en Visual C# en el panel de la izquierda y, después, haga clic en la plantilla Biblioteca de clases.In the Add New Project dialog box, choose Windows under Visual C# in the left pane, and then click the Class Library template.
  10. Asigne un nombre al proyecto ContosoAdsCommony haga clic en Aceptar.Name the project ContosoAdsCommon, and then click OK.

    Necesita hace referencia al contexto de Entity Framework y al modelo de datos de los proyectos de rol web y de trabajo.You need to reference the Entity Framework context and the data model from both web and worker role projects. Como alternativa, podría definir las clases relacionadas con EF en el proyecto de rol web y hacer referencia a ese proyecto desde el proyecto de rol de trabajo.As an alternative, you could define the EF-related classes in the web role project and reference that project from the worker role project. Pero en este enfoque alternativo, el proyecto de rol de trabajo tendría que hacer referencia a ensamblados web que no necesita.But in the alternative approach, your worker role project would have a reference to web assemblies that it doesn't need.

Actualizar y agregar paquetes de NuGetUpdate and add NuGet packages

  1. Abra el cuadro de diálogo Administrar paquetes de NuGet correspondiente a la solución.Open the Manage NuGet Packages dialog box for the solution.
  2. En la parte superior de la ventana, seleccione Actualizaciones.At the top of the window, select Updates.
  3. Busque el paquete WindowsAzure.Storage y, si está en la lista, selecciónelo, elija los proyectos web y de trabajo en los que actualizarlo y, después, haga clic en Actualizar.Look for the WindowsAzure.Storage package, and if it's in the list, select it and select the web and worker projects to update it in, and then click Update.

    La biblioteca de cliente de almacenamiento se actualiza con más frecuencia que las plantillas de proyecto de Visual Studio, por lo que verá que es necesario actualizar la versión de un proyecto recién creado.The storage client library is updated more frequently than Visual Studio project templates, so you'll often find that the version in a newly-created project needs to be updated.

  4. En la parte superior de la ventana, seleccione Examinar.At the top of the window, select Browse.
  5. Busque el paquete NuGet de EntityFramework e instálelo en los otros tres proyectos.Find the EntityFramework NuGet package, and install it in all three projects.
  6. Busque el paquete NuGet Microsoft.WindowsAzure.ConfigurationManager e instálelo en el proyecto de rol de trabajo.Find the Microsoft.WindowsAzure.ConfigurationManager NuGet package, and install it in the worker role project.

Establecimiento de preferencias del proyectoSet project references

  1. En el proyecto ContosoAdsWeb, establezca una referencia al proyecto ContosoAdsCommon.In the ContosoAdsWeb project, set a reference to the ContosoAdsCommon project. Haga clic con el botón derecho en el proyecto ContosoAdsWeb y después haga clic en Referencias - Agregar referencias.Right-click the ContosoAdsWeb project, and then click References - Add References. En el cuadro de diálogo Administrador de referencias, seleccione Solución – Proyectos en el panel izquierdo, seleccione ContosoAdsCommon y haga clic en Aceptar.In the Reference Manager dialog box, select Solution – Projects in the left pane, select ContosoAdsCommon, and then click OK.
  2. En el proyecto ContosoAdsWorker, establezca una referencia al proyecto ContosAdsCommon.In the ContosoAdsWorker project, set a reference to the ContosAdsCommon project.

    ContosoAdsCommon contendrá el modelo de datos y la clase de contexto de Entity Framework, que usarán tanto el front-end como el back-end.ContosoAdsCommon will contain the Entity Framework data model and context class, which will be used by both the front-end and back-end.

  3. En el proyecto ContosoAdsWorker, establezca una referencia en System.Drawing.In the ContosoAdsWorker project, set a reference to System.Drawing.

    Este ensamblado lo usa el back-end para convertir imágenes en miniaturas.This assembly is used by the back-end to convert images to thumbnails.

Configurar cadenas de conexiónConfigure connection strings

En esta sección configurará Azure Storage y cadenas de conexión de SQL para pruebas locales.In this section, you configure Azure Storage and SQL connection strings for testing locally. Las instrucciones de implementación que aparecen anteriormente en el tutorial explican cómo configurar las cadenas de conexión para cuando la aplicación se ejecuta en la nube.The deployment instructions earlier in the tutorial explain how to set up the connection strings for when the app runs in the cloud.

  1. En el proyecto ContosoAdsWeb, abra el archivo Web.config de la aplicación e inserte el siguiente elemento connectionStrings después del elemento configSections.In the ContosoAdsWeb project, open the application Web.config file, and insert the following connectionStrings element after the configSections element.

    <connectionStrings>
        <add name="ContosoAdsContext" connectionString="Data Source=(localdb)\v11.0; Initial Catalog=ContosoAds; Integrated Security=True; MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
    </connectionStrings>
    

    Si va a usar Visual Studio 2015 o una versión superior, sustituya "v11.0" por "MSSQLLocalDB".If you're using Visual Studio 2015 or higher, replace "v11.0" with "MSSQLLocalDB".

  2. Guarde los cambios.Save your changes.
  3. En el proyecto ContosoAdsCloudService, haga clic con el botón derecho en ContosoAdsWeb bajo Roles y después haga clic en Propiedades.In the ContosoAdsCloudService project, right-click ContosoAdsWeb under Roles, and then click Properties.

    Role properties

  4. En la ventana de propiedades del rol ContosoAdsWeb, haga clic en la pestaña Configuración y en Agregar configuración.In the ContosAdsWeb [Role] properties window, click the Settings tab, and then click Add Setting.

    Deje Configuración del servicio establecido en Todas las configuraciones.Leave Service Configuration set to All Configurations.

  5. Agregue un nuevo valor llamado StorageConnectionString.Add a setting named StorageConnectionString. Establezca Tipo en ConnectionString y Valor en UseDevelopmentStorage=true.Set Type to ConnectionString, and set Value to UseDevelopmentStorage=true.

    New connection string

  6. Guarde los cambios.Save your changes.
  7. Siga el mismo procedimiento para agregar una cadena de conexión en las propiedades del rol ContosoAdsWorker.Follow the same procedure to add a storage connection string in the ContosoAdsWorker role properties.
  8. Todavía en la ventana de propiedades ContosoAdsWorker [Rol] , agregue otra cadena de conexión:Still in the ContosoAdsWorker [Role] properties window, add another connection string:

    • Nombre: ContosoAdsDbConnectionStringName: ContosoAdsDbConnectionString
    • Tipo: StringType: String
    • Valor: pegue la misma cadena de conexión que usó para el proyecto de rol web.Value: Paste the same connection string you used for the web role project. (En el ejemplo siguiente es para Visual Studio 2013.(The following example is for Visual Studio 2013. No olvide cambiar el origen de datos si copia este ejemplo y va a usar Visual Studio 2015 o una versión superior).Don't forget to change the Data Source if you copy this example and you're using Visual Studio 2015 or higher.)

      Data Source=(localdb)\v11.0; Initial Catalog=ContosoAds; Integrated Security=True; MultipleActiveResultSets=True;
      

Agregar archivos de códigoAdd code files

En esta sección copiará archivos de código de la solución descargada a la nueva solución.In this section, you copy code files from the downloaded solution into the new solution. En las siguientes secciones se muestran y explican partes clave de este código.The following sections will show and explain key parts of this code.

Para agregar archivos a un proyecto o carpeta, haga clic con el botón derecho en dicho proyecto o carpeta y después en Agregar - Elemento existente.To add files to a project or a folder, right-click the project or folder and click Add - Existing Item. Seleccione los archivos que desee y haga clic en Agregar.Select the files you want and then click Add. Si se le pregunta si desea reemplazar los archivos existentes, haga clic en .If asked whether you want to replace existing files, click Yes.

  1. En el proyecto ContosoAdsCommon, elimine el archivo Class1.cs y agregue en su lugar los archivos Ad.cs y ContosoAdscontext.cs desde el proyecto descargado.In the ContosoAdsCommon project, delete the Class1.cs file and add in its place the Ad.cs and ContosoAdscontext.cs files from the downloaded project.
  2. En el proyecto ContosoAdsWeb, agregue los siguientes archivos desde el proyecto descargado.In the ContosoAdsWeb project, add the following files from the downloaded project.

    • Global.asax.cs.Global.asax.cs.
    • En la carpeta Views\Shared: _Layout.cshtml.In the Views\Shared folder: _Layout.cshtml.
    • En la carpeta Views\Home: Index.cshtml.In the Views\Home folder: Index.cshtml.
    • En la carpeta Controllers: AdController.cs.In the Controllers folder: AdController.cs.
    • En la carpeta Views\Ad (cree primero la carpeta): cinco archivos .cshtml.In the Views\Ad folder (create the folder first): five .cshtml files.
  3. En el proyecto ContosoAdsWorker, agregue WorkerRole.cs desde el proyecto descargado.In the ContosoAdsWorker project, add WorkerRole.cs from the downloaded project.

Ahora puede compilar y ejecutar la aplicación tal y como se indicó anteriormente en el tutorial y dicha aplicación usará los recursos de base de datos local y del emulador de almacenamiento.You can now build and run the application as instructed earlier in the tutorial, and the app will use local database and storage emulator resources.

En la siguiente sección se explica el código relacionado para trabajar con el entorno, blobs y colas de Azure.The following sections explain the code related to working with the Azure environment, blobs, and queues. En este tutorial no se explica cómo crear controladores y vistas MVC usando scaffolding, cómo escribir código Entity Framework que funcione con bases de datos de SQL Server o los fundamentos de la programación asincrónica en ASP.NET 4.5.This tutorial does not explain how to create MVC controllers and views using scaffolding, how to write Entity Framework code that works with SQL Server databases, or the basics of asynchronous programming in ASP.NET 4.5. Para obtener más información sobre estos temas, consulte los siguientes recursos:For information about these topics, see the following resources:

ContosoAdsCommon - Ad.csContosoAdsCommon - Ad.cs

El archivo Ad.cs define una enumeración para categorías de anuncios y una clase de entidad POCO para información de anuncios.The Ad.cs file defines an enum for ad categories and a POCO entity class for ad information.

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.csContosoAdsCommon - ContosoAdsContext.cs

La clase ContosoAdsContext especifica que la clase Ad se usa en una colección DbSet, cuyo Entity Framework se almacenará en una base de datos SQL.The ContosoAdsContext class specifies that the Ad class is used in a DbSet collection, which Entity Framework will store in a SQL database.

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 clase tiene dos constructores.The class has two constructors. El primero de ellos lo usa el proyecto web y especifica el nombre de una cadena de conexión que se almacena en el archivo Web.config.The first of them is used by the web project, and specifies the name of a connection string that is stored in the Web.config file. El segundo constructor le permite pasar la cadena de conexión real usada por el proyecto de rol de trabajo, ya que no tiene un archivo Web.config.The second constructor enables you to pass in the actual connection string used by the worker role project, since it doesn't have a Web.config file. Anteriormente vio dónde se almacenaba esta cadena de conexión y posteriormente verá cómo el código recupera dicha cadena de conexión cuando crea instancias de la clase DbContext.You saw earlier where this connection string was stored, and you'll see later how the code retrieves the connection string when it instantiates the DbContext class.

ContosoAdsWeb - Global.asax.csContosoAdsWeb - Global.asax.cs

El código llamado desde el método Application_Start crea un contenedor de blob images y una cola images si todavía no existen.Code that is called from the Application_Start method creates an images blob container and an images queue if they don't already exist. Esto garantiza que siempre que comience a usar una nueva cuenta de almacenamiento o el emulador de almacenamiento en un nuevo equipo, el contenedor de blobs requerido y la cola se crearán automáticamente.This ensures that whenever you start using a new storage account, or start using the storage emulator on a new computer, the required blob container and queue will be created automatically.

El código obtiene acceso a la cuenta de almacenamiento usando la cadena de conexión de almacenamiento del archivo .cscfg .The code gets access to the storage account by using the storage connection string from the .cscfg file.

var storageAccount = CloudStorageAccount.Parse
    (RoleEnvironment.GetConfigurationSettingValue("StorageConnectionString"));

Después obtiene una referencia al contenedor de blobs images , crea el contenedor si todavía no existe y establece permisos de acceso en el nuevo contenedor.Then it gets a reference to the images blob container, creates the container if it doesn't already exist, and sets access permissions on the new container. De forma predeterminada, los nuevos contenedores solamente permiten a los clientes con credenciales de cuenta de almacenamiento acceder a blobs.By default, new containers only allow clients with storage account credentials to access blobs. El sitio web necesita que los blobs sean públicos para que pueda mostrar imágenes usando direcciones URL que apunten a los blobs de imagen.The website needs the blobs to be public so that it can display images using URLs that point to the image blobs.

var blobClient = storageAccount.CreateCloudBlobClient();
var imagesBlobContainer = blobClient.GetContainerReference("images");
if (imagesBlobContainer.CreateIfNotExists())
{
    imagesBlobContainer.SetPermissions(
        new BlobContainerPermissions
        {
            PublicAccess =BlobContainerPublicAccessType.Blob
        });
}

El código similar obtiene una referencia a la cola images y crea una nueva cola.Similar code gets a reference to the images queue and creates a new queue. En este caso no es necesario cambios de permiso.In this case, no permissions change is needed.

CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
var imagesQueue = queueClient.GetQueueReference("images");
imagesQueue.CreateIfNotExists();

ContosoAdsWeb - _Layout.cshtmlContosoAdsWeb - _Layout.cshtml

El archivo _Layout.cshtml establece el nombre de aplicación en el encabezado y pie de página, y crea una entrada de menú "Ads".The _Layout.cshtml file sets the app name in the header and footer, and creates an "Ads" menu entry.

ContosoAdsWeb - Views\Home\Index.cshtmlContosoAdsWeb - Views\Home\Index.cshtml

El archivo Views\Home\Index.cshtml muestra vínculos de categoría en la página principal.The Views\Home\Index.cshtml file displays category links on the home page. Los vínculos pasan el valor entero de la enumeración Category en una variable de cadena de consulta a la página de índice de anuncios.The links pass the integer value of the Category enum in a querystring variable to the Ads Index page.

<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.csContosoAdsWeb - AdController.cs

En el archivo AdController.cs, el constructor llama al método InitializeStorage para crear objetos de biblioteca de cliente de Azure Storage que proporcionan una API para trabajar con blobs y colas.In the AdController.cs file, the constructor calls the InitializeStorage method to create Azure Storage Client Library objects that provide an API for working with blobs and queues.

Después, el código obtiene una referencia al contenedor de blobs images tal y como vio antes en Global.asax.cs.Then the code gets a reference to the images blob container as you saw earlier in Global.asax.cs. Mientras hace eso, establece una directiva de reintentos apropiada para una aplicación web.While doing that it sets a default retry policy appropriate for a web app. La directiva de reintentos de retroceso exponencial predeterminada podría bloquear la aplicación web durante más de un minuto en reintentos repetitivos para un error transitorio.The default exponential backoff retry policy could hang the web app for longer than a minute on repeated retries for a transient fault. La directiva de reintentos especificada aquí espera tres segundos después de cada reintento hasta tres reintentos.The retry policy specified here waits three seconds after each try for up to three tries.

var blobClient = storageAccount.CreateCloudBlobClient();
blobClient.DefaultRequestOptions.RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(3), 3);
imagesBlobContainer = blobClient.GetContainerReference("images");

El código similar obtiene una referencia a la cola images .Similar code gets a reference to the images queue.

CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
queueClient.DefaultRequestOptions.RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(3), 3);
imagesQueue = queueClient.GetQueueReference("images");

La mayoría del código del controlador es típico para trabajar con un modelo de datos de usando Entity Framework usando una clase DbContext.Most of the controller code is typical for working with an Entity Framework data model using a DbContext class. Una excepción es el método HttpPost Create , que carga un archivo y lo guarda en el almacenamiento de blobs.An exception is the HttpPost Create method, which uploads a file and saves it in blob storage. El enlazador de modelos proporciona un objeto HttpPostedFileBase al método.The model binder provides an HttpPostedFileBase object to the method.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(
    [Bind(Include = "Title,Price,Description,Category,Phone")] Ad ad,
    HttpPostedFileBase imageFile)

Si el usuario seleccionó un archivo para cargar, el código carga el archivo, lo guarda en un blob y actualiza el registro de base de datos Ad con una dirección URL que adjunta al blob.If the user selected a file to upload, the code uploads the file, saves it in a blob, and updates the Ad database record with a URL that points to the blob.

if (imageFile != null && imageFile.ContentLength != 0)
{
    blob = await UploadAndSaveBlobAsync(imageFile);
    ad.ImageURL = blob.Uri.ToString();
}

El código que no se carga se encuentra en el método UploadAndSaveBlobAsync .The code that does the upload is in the UploadAndSaveBlobAsync method. Crea un nombre GUID para el blob, carga y guarda el archivo y devuelve una referencia al blob guardado.It creates a GUID name for the blob, uploads and saves the file, and returns a reference to the saved blob.

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;
}

Después de que el método Create HttpPost carga un blob y actualiza la base de datos, crea un mensaje de cola para informar a ese proceso back-end que una imagen está preparada para su conversión en una miniatura.After the HttpPost Create method uploads a blob and updates the database, it creates a queue message to inform that back-end process that an image is ready for conversion to a thumbnail.

string queueMessageString = ad.AdId.ToString();
var queueMessage = new CloudQueueMessage(queueMessageString);
await queue.AddMessageAsync(queueMessage);

El código para el método Edit HttpPost es similar con la excepción de que si el usuario selecciona un archivo de imagen nuevo, cualquier blob que ya exista se debe eliminar.The code for the HttpPost Edit method is similar except that if the user selects a new image file any blobs that already exist must be deleted.

if (imageFile != null && imageFile.ContentLength != 0)
{
    await DeleteAdBlobsAsync(ad);
    imageBlob = await UploadAndSaveBlobAsync(imageFile);
    ad.ImageURL = imageBlob.Uri.ToString();
}

En el siguiente ejemplo se muestra el código que elimina blobs cuando elimina un anuncio.The next example shows the code that deletes blobs when you delete an ad.

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 y Details.cshtmlContosoAdsWeb - Views\Ad\Index.cshtml and Details.cshtml

El archivo Index.cshtml muestra miniaturas con otros datos de anuncio.The Index.cshtml file displays thumbnails with the other ad data.

<img src="@Html.Raw(item.ThumbnailURL)" />

El archivo Details.cshtml muestra la imagen a tamaño completo.The Details.cshtml file displays the full-size image.

<img src="@Html.Raw(Model.ImageURL)" />

ContosoAdsWeb - Views\Ad\Create.cshtml y Edit.cshtmlContosoAdsWeb - Views\Ad\Create.cshtml and Edit.cshtml

Los archivos Create.cshtml y Edit.cshtml especifican una codificación de formularios que permite al controlador obtener el objeto HttpPostedFileBase.The Create.cshtml and Edit.cshtml files specify form encoding that enables the controller to get the HttpPostedFileBase object.

@using (Html.BeginForm("Create", "Ad", FormMethod.Post, new { enctype = "multipart/form-data" }))

Un elemento <input> indica al explorador que proporcione un cuadro de dialogo de selección.An <input> element tells the browser to provide a file selection dialog.

<input type="file" name="imageFile" accept="image/*" class="form-control fileupload" />

ContosoAdsWorker - WorkerRole.cs - Método OnStartContosoAdsWorker - WorkerRole.cs - OnStart method

El entorno del rol de trabajo de Azure llama al método OnStart en la clase WorkerRole cuando el rol de trabajo se inicia, y llama al método Run cuando el método OnStart finaliza.The Azure worker role environment calls the OnStart method in the WorkerRole class when the worker role is getting started, and it calls the Run method when the OnStart method finishes.

El método OnStart obtiene la cadena de conexión de base de datos del archivo .cscfg y la pasa a la clase DbContext de Entity Framework.The OnStart method gets the database connection string from the .cscfg file and passes it to the Entity Framework DbContext class. El proveedor SQLClient se usa de forma predeterminada, por lo que no es necesario especificar el proveedor.The SQLClient provider is used by default, so the provider does not have to be specified.

var dbConnString = CloudConfigurationManager.GetSetting("ContosoAdsDbConnectionString");
db = new ContosoAdsContext(dbConnString);

Después, el método obtiene una referencia a la cuenta de almacenamiento y crea el contenedor de blobs y la cola si no existen.After that, the method gets a reference to the storage account and creates the blob container and queue if they don't exist. El código para ello es similar al que ya vio en el método Application_Start del rol web.The code for that is similar to what you already saw in the web role Application_Start method.

ContosoAdsWorker - WorkerRole.cs - Método RunContosoAdsWorker - WorkerRole.cs - Run method

El método Run se llama cuando el método OnStart finaliza su trabajo de inicialización.The Run method is called when the OnStart method finishes its initialization work. El método ejecuta un bucle infinito que busca nuevos mensajes de cola y los procesa cuando llegan.The method executes an infinite loop that watches for new queue messages and processes them when they arrive.

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);
        }
    }
}

Después de cada iteración del bucle, si no se encuentra ningún mensaje de cola, el programa entra en estado de suspensión durante un segundo.After each iteration of the loop, if no queue message was found, the program sleeps for a second. Esto evita que el rol de trabajo incurra en costos de tiempo de CPU y de transacción de almacenamiento excesivos.This prevents the worker role from incurring excessive CPU time and storage transaction costs. Microsoft Customer Advisory Team narra un relato sobre un desarrollador que olvidó incluir esto, lo mandó a producción y se fue de vacaciones.The Microsoft Customer Advisory Team tells a story about a developer who forgot to include this, deployed to production, and left for vacation. Cuando volvió, su descuido le costó algo más que las vacaciones.When he got back, his oversight cost more than the vacation.

Algunas veces, el contenido de un mensaje de cola causa un error de procesamiento.Sometimes the content of a queue message causes an error in processing. Esto se llama mensaje dudosoy si simplemente registró un error y reinició el bucle, podría intentar procesar ese mensaje incesantemente.This is called a poison message, and if you just logged an error and restarted the loop, you could endlessly try to process that message. Por tanto, el bloque de captura incluye una declaración if que comprueba el número de veces que la aplicación ha intentado procesar el mensaje actual y, si dicho número es superior a 5, el mensaje se elimina de la cola.Therefore the catch block includes an if statement that checks to see how many times the app has tried to process the current message, and if it has been more than 5 times, the message is deleted from the queue.

ProcessQueueMessage se llama cuando se encuentra un mensaje de cola.ProcessQueueMessage is called when a queue message is found.

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 lee la base de datos para obtener la dirección URL de la imagen, convierte la imagen en una miniatura, guarda la miniatura en un blob, actualiza la base de datos con la dirección URL del blob de la miniatura y elimina el mensaje de cola.This code reads the database to get the image URL, converts the image to a thumbnail, saves the thumbnail in a blob, updates the database with the thumbnail blob URL, and deletes the queue message.

Nota

El código del método ConvertImageToThumbnailJPG usa clases del espacio de nombres System.Drawing por simplicidad.The code in the ConvertImageToThumbnailJPG method uses classes in the System.Drawing namespace for simplicity. Sin embargo, las clases de este espacio de nombres se diseñaron para usarse con Windows Forms.However, the classes in this namespace were designed for use with Windows Forms. No se admiten para usarse en un servicio de Windows o ASP.NET.They are not supported for use in a Windows or ASP.NET service. Para más información acerca de las opciones de procesamiento de imagen, consulte Dynamic Image Generation (Generación de imagen dinámica) y Deep Inside Image Resizing (Profundización en el cambio de tamaño de imágenes).For more information about image-processing options, see Dynamic Image Generation and Deep Inside Image Resizing.

solución de problemasTroubleshooting

En el caso de que algo no funcionen a pesar de seguir las instrucciones de este tutorial, aquí tiene algunos errores comunes y cómo resolverlos.In case something doesn't work while you're following the instructions in this tutorial, here are some common errors and how to resolve them.

ServiceRuntime.RoleEnvironmentExceptionServiceRuntime.RoleEnvironmentException

El objeto RoleEnvironment lo proporciona Azure cuando se ejecuta una aplicación en Azure o cuando se ejecuta localmente usando el emulador de proceso de Azure.The RoleEnvironment object is provided by Azure when you run an application in Azure or when you run locally using the Azure compute emulator. Si aparece este error cuando la ejecución se realiza localmente, asegúrese de que ha establecido el proyecto ContosoAdsCloudService como el proyecto de inicio.If you get this error when you're running locally, make sure that you have set the ContosoAdsCloudService project as the startup project. Esto configura el proyecto para ejecutarse usando el emulador de proceso de Azure.This sets up the project to run using the Azure compute emulator.

Una de las cosas para las que la aplicación usa RoleEnvironment de Azure es para conseguir valores de cadena de conexión almacenados en los archivos .cscfg , por lo que otra causa de esta excepción es la ausencia de una cadena de conexión.One of the things the application uses the Azure RoleEnvironment for is to get the connection string values that are stored in the .cscfg files, so another cause of this exception is a missing connection string. Asegúrese de que creó el valor StorageConnectionString para las configuraciones Nube y Local en el proyecto ContosoAdsWeb y que creó ambas cadenas de conexión para las dos configuraciones en el proyecto ContosoAdsWorker.Make sure that you created the StorageConnectionString setting for both Cloud and Local configurations in the ContosoAdsWeb project, and that you created both connection strings for both configurations in the ContosoAdsWorker project. Si busca StorageConnectionString mediante Buscar todo en toda la solución, verá que aparece 9 veces en 6 archivos.If you do a Find All search for StorageConnectionString in the entire solution, you should see it 9 times in 6 files.

No se puede invalidar el puerto xxx.Cannot override to port xxx. El nuevo puerto está por debajo del valor mínimo permitido de 8080 para el protocolo http.New port below minimum allowed value 8080 for protocol http

Intente cambiar el número de puerto usado por el proyecto web.Try changing the port number used by the web project. Haga clic con el botón derecho en el proyecto ContosoAdsWeb y después haga clic en Propiedades.Right-click the ContosoAdsWeb project, and then click Properties. Haga clic en la pestaña Web y después cambie el número de puerto en el valor URL del proyecto.Click the Web tab, and then change the port number in the Project Url setting.

Para conocer otra alternativa que podría resolver el problema, consulte la sección siguiente.For another alternative that might resolve the problem, see the following section.

Otros errores al realizar la ejecución localmenteOther errors when running locally

De forma predeterminada, los nuevos proyectos de servicio en la nube usan el emulador de proceso de Azure rápido para simular el entorno de Azure.By default new cloud service projects use the Azure compute emulator express to simulate the Azure environment. Se trata de una versión ligera del emulador de proceso completo y, en determinadas circunstancias, el emulador completo funcionará cuando la versión rápida no lo haga.This is a lightweight version of the full compute emulator, and under some conditions the full emulator will work when the express version does not.

Para cambiar el proyecto para que use el emulador completo, haga clic con el botón derecho en el proyecto ContosoAdsCloudService y después haga clic en Propiedades.To change the project to use the full emulator, right-click the ContosoAdsCloudService project, and then click Properties. En la ventana Propiedades, haga clic en la pestaña Web y después en el botón de radio Usar emulador completo.In the Properties window click the Web tab, and then click the Use Full Emulator radio button.

Para ejecutar la aplicación con el emulador completo, tiene que abrir Visual Studio con privilegios de administrador.In order to run the application with the full emulator, you have to open Visual Studio with administrator privileges.

Pasos siguientesNext steps

La aplicación Contoso Ads se ha diseñado de forma que resulte sencilla intencionadamente para un tutorial de inicio.The Contoso Ads application has intentionally been kept simple for a getting-started tutorial. Por ejemplo, no implementa la inserción de dependencias ni los patrones de repositorio y unidad de trabajo, no usa ninguna interfaz para registro, no usa migraciones de EF Code First para administrar cambios de modelos de datos ni la resistencia de conexiones EF para administrar errores de red transitorios, etc.For example, it doesn't implement dependency injection or the repository and unit of work patterns, it doesn't use an interface for logging, it doesn't use EF Code First Migrations to manage data model changes or EF Connection Resiliency to manage transient network errors, and so forth.

A continuación se muestran algunas aplicaciones de ejemplo de servicios en la nube que muestran más procedimientos de codificación reales, enumeradas desde la menos compleja a la más compleja:Here are some cloud service sample applications that demonstrate more real-world coding practices, listed from less complex to more complex:

Para obtener información general sobre el desarrollo para la nube, consulte Creación de aplicaciones del mundo real para la nube con Azure.For general information about developing for the cloud, see Building Real-World Cloud Apps with Azure.

Para ver un vídeo introductorio de los procedimientos y modelos recomendados de Azure Storage, consulte Microsoft Azure Storage: novedades, procedimientos y modelos recomendados.For a video introduction to Azure Storage best practices and patterns, see Microsoft Azure Storage – What's New, Best Practices and Patterns.

Para obtener más información, consulte los siguientes recursos:For more information, see the following resources: