Sometimes a web service requires us to pass a binary file, such as an image in the request body.

To do this, we need to submit the request with the POST verb, because other verbs - most notably "GET" - do not contain a body.

One simple web service that accepts a binary file is the Cognitive Services Image Analysis API. This API is fully documented here.

I created a console application (the simplest .NET app I can think of) to demonstrate how to pass the binary image to the web service. This application is named "ImageAnalysisConsoleAppDemo" and is included in my Cognitive Services demos, which you can download here.

Assumptions

Before you get started, you will need to create a Computer Vision Cognitive Service, as described here.

I have hard-coded the file name and location, along with the Cognitive Services URL, but you can change these to match what you are using. You will also need to add your API key to the App.config file.

The code

The first thing we need to do is to read the file and convert it into an array of bytes. The code to do this is in Listing 1 below.

Listing 1:

byte[] byteData; ;
using (FileStream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read))
{
    BinaryReader = new BinaryReader(fileStream);
    byteData = binaryReader.ReadBytes((int)fileStream.Length);
}
  

Next, we call the web service, passing the byte array. The System.Net.Http client library helps us to make this call. Notice the "using" construct that converts the byte array into a ByteArrayContent object that is required by the library.

Within that "using", we make an asynchronous call to the web service and capture the results.

Listing 2 shows this code.

Listing 2:

var cogSvcUrl = "https://westus.api.cognitive.microsoft.com/vision/v2.0/analyze?visualFeatures=Description&language=en"; 
HttpClient client = new HttpClient(); 
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", computerVisionKey); 
HttpResponseMessage response; 
using (ByteArrayContent content = new ByteArrayContent(byteData)) 
{ 
    content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
    response = await client.PostAsync(cogSvcUrl, content); 
}
  

Finally, we convert the results to a string, as shown in Listing 3. This web service returns JSON containing either information about the image or an error message.

Listing 3:

string webServiceResponseContent = await response.Content.ReadAsStringAsync();
  

Here is the full code:

Listing 4:

using System;
using System.Configuration;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace ImageAnalysisConsoleAppDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            MainAsync().Wait();
            Console.ReadLine();
        }

        static async Task MainAsync()
        {
            string key = GetKey();
            string imageFilePath = @"c:\test\kittens.jpg";
            if (!File.Exists(imageFilePath))
            {
                Console.WriteLine("File {0} does not exist", imageFilePath);
                return;
            }
            string results = await GetRecognizeTextOperationResultsFromFile(imageFilePath, key);
            Console.WriteLine(results);
        }


        public static async Task<string> GetRecognizeTextOperationResultsFromFile(string imageFilePath, string computerVisionKey)
        {
            // Convert file into Byte Array
            byte[] byteData; ;
            using (FileStream fileStream = new FileStream(imageFilePath, FileMode.Open, FileAccess.Read))
            {
                BinaryReader binaryReader = new BinaryReader(fileStream);
                byteData = binaryReader.ReadBytes((int)fileStream.Length);
            }

            // Make web service call. Pass byte array in body
            var cogSvcUrl = "https://westus.api.cognitive.microsoft.com/vision/v2.0/analyze?visualFeatures=Description&language=en";
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", computerVisionKey);
            HttpResponseMessage response;
            using (ByteArrayContent content = new ByteArrayContent(byteData))
            {
                content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                response = await client.PostAsync(cogSvcUrl, content);
            }

            // Get results
            string webServiceResponseContent = await response.Content.ReadAsStringAsync();
            return webServiceResponseContent;
        }

        public static string GetKey()
        {
            string computerVisionKey = ConfigurationManager.AppSettings["ComputerVisionKey"];
            return computerVisionKey;
        }

    }
}
  

Fig. 1 shows the output when analyzing the image displayed in Fig. 2 (saved in “c:\test\kittens.jpg”).

AnalyzeImage
Fig. 1

Kittens
Fig. 2

This code is not complex, but it is not intuitive (at least not, to me). So, it's useful to understand how to write C# code to pass a binary file to a web service.