Events
Mar 17, 9 PM - Mar 21, 10 AM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Sometimes developers must have full control of how data is returned from a service operation. This is the case when a service operation must return data in a format not supported by WCF. This topic discusses using the WCF WEB HTTP Programming Model to create such a service. This service has one operation that returns a stream.
Define the service contract. The contract is called IImageServer
and has one method called GetImage
that returns a Stream.
[ServiceContract]
public interface IImageServer
{
[WebGet]
Stream GetImage(int width, int height);
}
Because the method returns a Stream, WCF assumes that the operation has complete control over the bytes that are returned from the service operation and it applies no formatting to the data that is returned.
Implement the service contract. The contract has only one operation (GetImage
). This method generates a bitmap and then save it to a MemoryStream in .jpg format. The operation then returns that stream to the caller.
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;
}
}
Notice the second to last line of code: WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
This sets the content type header to "image/jpeg"
. Although this sample shows how to return a .jpg file, it can be modified to return any type of data that is required, in any format. The operation must retrieve or generate the data and then write it to a stream.
Create a console application to host the service.
class Program
{
static void Main(string[] args)
{
}
}
Create a variable to hold the base address for the service within the Main
method.
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
Create a ServiceHost instance for the service specifying the service class and the base address.
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
Add an endpoint using the WebHttpBinding and the WebHttpBehavior.
host.AddServiceEndpoint(typeof(IImageServer), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
Open the service host.
host.Open();
Wait until the user presses Enter to terminate the service.
Console.WriteLine("Service is running");
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
Run the service, you should see the following output from the service: Service is running Press ENTER to close the host
Open a web browser and enter http://localhost:8000/Service/GetImage?width=50&height=40
. You should see a yellow rectangle with a blue diagonal line through the center.
The following is a complete listing of the code for this topic.
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();
}
}
}
When compiling the sample code, reference System.ServiceModel.dll and System.ServiceModel.Web.dll.
Events
Mar 17, 9 PM - Mar 21, 10 AM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowTraining
Module
Implement HTTP operations in ASP.NET Core Blazor Web apps - Training
Implement HTTP operations in ASP.NET Core Blazor Web apps
Documentation
How to: Create a Service That Accepts Arbitrary Data using the WCF REST Programming Model - WCF
Learn more about: How to: Create a Service That Accepts Arbitrary Data using the WCF REST Programming Model
WCF Web HTTP Programming Model Overview - WCF
Learn more about: WCF Web HTTP Programming Model Overview
WCF Web HTTP Programming Object Model - WCF
Learn more about: WCF Web HTTP Programming Object Model