Media Formatters in ASP.NET Web API

Introduction

In this article we will define the Media Type Formatters used in ASP.NET Web API.

What is the Media Type

Media Type is called the Internet Media Type and also called Multipurpose Internet Mail Extensions (MIME). Media Type determines the format of the data. For HTTP the Media Type sets the format of the message body. The Media Type holds two strings that are as follows:

  1. text/html
  2. application/json

Media Type Formatter in Web API

The Media Type Formatter in the Web API defines how the message body is serialized and desterilized. How to serialize the HTTP message and how to desterilize the HTTP message. It supports the XML and JSON formatters.

If you want to create the media formatter then we need to use the following classes:

  • MediaTypeFormatter: This class is a collection of asynchronous methods. These methods are used for both read and write.
  • BufferedMediaTypeFormatter: This class wraps all the asynchronous methods in synchronous methods.

Creation of Media Type formatter

Now we explain how to create the Media Type formatter. In this example there is an object that is serialized by the media formatter:

  1. namespace webapp  
  2. {  
  3.     public class Material  
  4.     {  
  5.         public int id { getset; }  
  6.         public string Mname { getset; }  
  7.         public decimal cost { getset; }  
  8.         public string Type { getset; }  
  9.     }  
  10. } 

Now we define the class that is derived from the BufferedMediaType Formatter:

  1. namespace webapp.Formatters  
  2. {  
  3.     using System;  
  4.     using System.Collections.Generic;  
  5.     using System.IO;  
  6.     using System.Net.Http.Formatting;  
  7.     using System.Net.Http.Headers;  
  8.     using webapp.Models;  
  9.     public class Material_Format : BufferedMediaTypeFormatter  
  10.     {  
  11.     }  
  12. } 

Now we add a constructor in which we add the supported Media Type:

  1. public Material_Format()  
  2. {  
  3.     SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));  
  4. }   

Now we override the method CanWriteType:

  1. public override bool CanWriteType(System.Type tp)  
  2. {  
  3.     if (tp == typeof(Matirial))  
  4.     {  
  5.         return true;  
  6.     }  
  7.     else  
  8.     {  
  9.         Type enum = typeof(IEnumerable<Material>);  
  10.         return enum.IsAssignableFrom(tp);  
  11.     }  
  12. } 

At last we override the WriteToStream method:

  1. public override void WriteToStream(Type tp, object obj, Stream stm, HttpContentHeaders cont)  
  2. {  
  3.     using (var wrt = new StreamWriter(stm))  
  4.     {  
  5.         var materials = value as IEnumerable<Material>;  
  6.         if (material != null)  
  7.         {  
  8.             foreach (var material in materials)  
  9.             {  
  10.                 WriteItem(material, wrt);  
  11.             }  
  12.         }  
  13.         else  
  14.         {  
  15.             var onematerial= value as Material;  
  16.             if (onematerial == null)  
  17.             {  
  18.                 throw new InvalidOperationException("it can not be serialized");  
  19.             }  
  20.             WriteItem(onematerial, wrt);  
  21.         }  
  22.     }  
  23.     stm.Close();  
  24. }  
  25. private void WriteItem(Material material, StreamWriter wrt)  
  26. {  
  27.     wrt.WriteLine("{0},{1},{2},{3}", Escape(material.Id),  
  28.         Escape(material.Name), Escape(material.Category), Escape(material.Price));  
  29. }  
  30. static char[] space = new char[] { ',''\n''\r''"' };  
  31. private string Escape(object obj1)  
  32. {  
  33.     if (obj1 == null)  
  34.     {  
  35.         return "";  
  36.     }  
  37.     string value = obj1.ToString();  
  38.     if (value.IndexOfAny(space) != -1)  
  39.     {  
  40.         return String.Format("\"{0}\"", value.Replace("\"""\"\""));  
  41.     }  
  42.     else  
  43.     return value;  
  44. }   

Adding the Media formatter

Here we create the object of HttpConfiguration for adding the formatter:

  1. public static void config(HttpConfiguration cn )  
  2. {  
  3.     cn.Formatters.Add(new Material_Format());  
  4. } 

Now we add this method into the Global.asax file in the Application_Start method for performing the hosting.

  1. void Application_Start(object sender, EventArgs e)  
  2. {  
  3.     protected void Application_Start()  
  4.     {  
  5.         config(GlobalConfiguration.Configuration);  
  6.     }  
  7. } 

After specifying the "text/html/ in the accept header then the server returns the response in HTML format.

  1. HttpClient htp = new HttpClient();  
  2. htp.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/html"));  
  3. string final = htp.GetStringAsync("localhost:35692/api/materials/").final;  
  4. System.IO.File.WriteAllText("materials.html", final);