Como: criar um serviço que retorna dados arbitrários usando o modelo de programação HTTP Web do WCF
Às vezes, os desenvolvedores precisam ter controle total de como os dados são retornados de uma operação de serviço. Este é o caso quando uma operação de serviço deve retornar dados em um formato não suportado pelo WCF. Este tópico discute o uso do WCF WEB HTTP Programming Model para criar tal serviço. Este serviço tem uma operação que retorna um fluxo.
Para implementar o contrato de serviço
Defina o contrato de serviço. O contrato é chamado
IImageServer
e tem um método chamadoGetImage
que retorna um Stream.[ServiceContract] public interface IImageServer { [WebGet] Stream GetImage(int width, int height); }
Como o método retorna um Stream, o WCF pressupõe que a operação tem controle total sobre os bytes retornados da operação de serviço e não aplica formatação aos dados retornados.
Implemente o contrato de serviço. O contrato tem apenas uma operação (
GetImage
). Esse método gera um bitmap e o salva em um MemoryStream no formato .jpg. A operação então retorna esse fluxo para o chamador.public class Service : IImageServer { public Stream GetImage(int width, int height) { Bitmap bitmap = new Bitmap(width, height); for (int i = 0; i < bitmap.Width; i++) { for (int j = 0; j < bitmap.Height; j++) { bitmap.SetPixel(i, j, (Math.Abs(i - j) < 2) ? Color.Blue : Color.Yellow); } } MemoryStream ms = new MemoryStream(); bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); ms.Position = 0; WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg"; return ms; } }
Observe a penúltima linha de código:
WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
Isso define o cabeçalho do tipo de conteúdo como
"image/jpeg"
. Embora este exemplo mostre como retornar um arquivo .jpg, ele pode ser modificado para retornar qualquer tipo de dado necessário, em qualquer formato. A operação deve recuperar ou gerar os dados e, em seguida, gravá-los em um fluxo.
Para hospedar o serviço
Crie um projeto de aplicativo de console para hospedar o serviço.
class Program { static void Main(string[] args) { } }
Crie uma variável para manter o endereço básico do serviço dentro do método
Main
.string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
Crie uma instância ServiceHost para o serviço especificando a classe de serviço e o endereço base.
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
Adicione um endpoint usando o WebHttpBinding e o WebHttpBehavior.
host.AddServiceEndpoint(typeof(IImageServer), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
Abra o host do serviço.
host.Open();
Aguarde até que o usuário pressione Enter para encerrar o serviço.
Console.WriteLine("Service is running"); Console.Write("Press ENTER to close the host"); Console.ReadLine(); host.Close();
Para chamar o serviço bruto usando um navegador
Execute o serviço, você deverá ver a seguinte saída do serviço:
Service is running Press ENTER to close the host
Abra um navegador da Web e insira
http://localhost:8000/Service/GetImage?width=50&height=40
. Você verá um retângulo amarelo com uma linha diagonal azul no centro.
Exemplo
A seguir está uma lista completa do código para este tópico.
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.ServiceModel.Description;
using System.IO;
using System.Drawing;
namespace RawImageService
{
// Define the service contract
[ServiceContract]
public interface IImageServer
{
[WebGet]
Stream GetImage(int width, int height);
}
// implement the service contract
public class Service : IImageServer
{
public Stream GetImage(int width, int height)
{
// Although this method returns a jpeg, it can be
// modified to return any data you want within the stream
Bitmap bitmap = new Bitmap(width, height);
for (int i = 0; i < bitmap.Width; i++)
{
for (int j = 0; j < bitmap.Height; j++)
{
bitmap.SetPixel(i, j, (Math.Abs(i - j) < 2) ? Color.Blue : Color.Yellow);
}
}
MemoryStream ms = new MemoryStream();
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Position = 0;
WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
return ms;
}
}
class Program
{
static void Main(string[] args)
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(IImageServer), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
host.Open();
Console.WriteLine("Service is running");
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}
}
Compilando o código
Ao compilar a referência de código de exemplo System.ServiceModel.dll e System.ServiceModel.Web.dll.