Desplegar un servicio web con WCF en Azure App Service

Hacía mucho tiempo que no trasteaba con Windows Communication Foundation (como desde el 2009) y mucho menos sobre Microsoft Azure. Sin embargo, es de esperar que muchas empresas todavía tengan algunos de sus servicios construídos sobre esta tecnología. En este artículo quiero mostrarte cómo configurar tu servicio para desplegarlo en App Service.

Azure App Service utiliza HTTPS por defecto

En este caso estoy hablando de servicios que utilizan HTTP como protocolo de transporte, más en concreto webHttpBinding. Si tus servicios no están configurados para trabajar con HTTPS, cuando los despliegues en App Service verás que recibes un 404 al intentar invocar alguna de las operaciones que tienes definidas:

Esto es así porque App Service por defecto utiliza HTTPS para el transporte y necesitas modificar tu servicio para que el endpoint pueda trabajar de este modo.

Para este artículo he creado un proyecto de prueba, utilizando la plantilla de Visual Studio, donde he añadido un contrato como el siguiente:

using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;
using WcfService.DataContracts;

namespace WcfService
{
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        [WebInvoke(Method = "GET",
                   ResponseFormat = WebMessageFormat.Json,
                   RequestFormat = WebMessageFormat.Json,
                   BodyStyle = WebMessageBodyStyle.Bare,
                    UriTemplate = "/GetProductList")]
        List<Product> GetProductList();
    }
}

Utilizo un tipo complejo llamado Product:

using System.Runtime.Serialization;

namespace WcfService.DataContracts
{
    [DataContract]
    public class Product
    {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Category { get; set; }
        [DataMember]
        public double Price { get; set; }
    }
}

Y esta es la implementación del servicio:

using System.Collections.Generic;
using WcfService.DataContracts;

namespace WcfService
{
    public class Service : IService
    {
        public List<Product> GetProductList()
        {
            return new List<Product>
            {
                new Product() {Id = 1, Name = "Table", Category = "Dinning Room", Price = 100.5},
                new Product() {Id = 2, Name = "Bed", Category = "Bedroom", Price = 500.99},
                new Product() {Id = 3, Name = "Table", Category = "Kitchen Room", Price = 15},
                new Product() {Id = 4, Name = "Sink", Category = "Bathroom", Price = 90.5}
            };
        }
    }
}

En el archivo web.config debes de tener al menos una configuración como la que sigue para poder acceder al mismo desde App Service:

<system.serviceModel>
    <services>
      <service name="WcfService.Service">
        <endpoint behaviorConfiguration="webBehavior"
                  binding="webHttpBinding"
                  bindingConfiguration="secureHttpBinding"
                  contract="WcfService.IService" />        
      </service>
    </services>
    <bindings>
      <webHttpBinding>
        <binding name="secureHttpBinding">
          <security mode="Transport">
            <transport clientCredentialType="None"/>
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

Como puedes ver, he configurado para el binding de tipo webHttpBinding el modo Transport en el apartado security, del tal manera que el transporte sea seguro, lo cual significa que está utilizando HTTPS en lugar de HTTP.

Si lo despliegas con dicha configuración ya podrás migrar tus servicios web con WCF a Microsoft Azure.

¡Saludos!