Thursday 26 January 2017

How to create a custom media type formatter for accept type in Web api call

In this post we are going to create a custom media type formatter for accept type in web api call, Normally we are using the application/xml, text/xml format in accept while giving request.

In this sample we are going to take accept type as csv format for response type.

Steps to create a custom media type formatter.
1. Create a class which derived from BufferedMediaTypeformatter.
2. Make a condition for CanWriteType
3. Make a logic to WriteToStream
4. Add a format type in constructor in supportedMediaTypes.


    public class BlogCsvFormatter : BufferedMediaTypeFormatter
    {

        public BlogCsvFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/blog"));
        }

        public override bool CanReadType(Type type)
        {
            return false;
        }

        public override bool CanWriteType(Type type)
        {
            if(type == typeof(BlogModel))
            {
                return true;
            }
            else
            {
                Type t = typeof(IEnumerable<BlogModel>);
                return t.IsAssignableFrom(type);
            }
        }

        public override void WriteToStream(Type type, object value, 
               Stream writeStream, HttpContent content)
        {
            using(StreamWriter writer = new StreamWriter(writeStream))
            {
                var list = value as IEnumerable<BlogModel>;
                if (list != null)
                {
                    foreach (var item in list)
                    {
                        writer.Write(string.Format(
         "{0},\"{1}\",\"{2}\",\"{3}\"\n",item.Id,item.Name,item.NoOfPosts,item.Createdby));
                    }
                }
                else
                {
                    var item = value as BlogModel;
                    if (item == null)
                        throw new InvalidOperationException("Cant able to serialize");

                    writer.Write(string.Format(
        "{0},\"{1}\",\"{2}\",\"{3}\"\n", item.Id, item.Name, item.NoOfPosts, item.Createdby));
                }
            }

        }

    }


Add the custom formatter in web api config


    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();
            config.Formatters.Add(new BlogCsvFormatter());

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

    }



Create a controller logic with get where it return the all blog ids.

   public class BlogModel
    {
        public int Id { set; get; }

        public string Name { set; get; }

        public string Createdby { set; get; }

        public int NoOfPosts { set; get; }
    }

   public class BlogController : ApiController
    {

        public IEnumerable<BlogModel>  GetBlogs()
        {
            List<BlogModel> blogs = new List<BlogModel>();

            blogs.Add(new BlogModel() { 
                    Id = 1,Name="DotnetVisio",Createdby="Rajesh",NoOfPosts=400 });

            blogs.Add(new BlogModel() { 
                    Id = 2, Name = "Angularjs", Createdby = "Rajesh", NoOfPosts = 50 });

            blogs.Add(new BlogModel() { 
                    Id = 3, Name = "SqlServer", Createdby = "Suresh", NoOfPosts = 250 });

            return blogs;
        }


}


While giving request we have to give accept as following to get the custom format to execute when we give request with accept as application/blog our custom formatter will execute

url : http://localhost:57437/api/blog

send request as
accept:application/xml

output: you may see it is in xml format







send request as
accept:application/blog

output: you may see it is in csv format based on our custom formatter , due to our request accept type output changes, you may see that the same url request return a collection in previous one , but here it is csv format.







From this post you can learn how to create a custom media type formatter for accept type in web api call.

2 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete