Web Api – Media Type Formatter – Notlar

Merhabalar ,

Media Type Formatter verimizi kullanıcılara hangi formatta sunacağımızı belirleyeceğimiz sanal bir sınıftır , yani bütün media typpe formatırlar bu sanal sınıftan miras alarak türemiştir

  • JsonMediaTypeFormatter
  • XmlMediaTypeFormatter
  • FormUrlEncodeMediaTypeFormatter

Default olarak Asp.Net Web Api de gelmektedir , istersek kendimizde yeni bir Media Type Formatter tanımlayabiliriz.

Örneğin Api mizde xml desteğini kaldırmak istesek App_Start kalsöründe bulunan WebApiConfig.cs dosyamızda aşşağıdaki kod satısını eklemeliyiz.

using : using System.Net.Http.Formatting;

code : config.Formatters.Remove(config.Formatters.XmlFormatter);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Net.Http.Formatting;

namespace WebApiApp
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

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

               
            );

            config.Formatters.Remove(config.Formatters.XmlFormatter);
        }
    }
}

Web apimize text/html tipinde bir accept istek olduğunda json formatında response dönmesi için config ayarı ekleme.

config satırımız : config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue(“text/html”));

json formatımızın desteklediği media type header değerlerine text/html eklemiş olduk

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Net.Http.Formatting;

namespace WebApiApp
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

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

               
            );

            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));
        }
    }
}

fakat bu şekilde bir kullanımda text/html olarak gelen bir accept te response olarak json döncektir ama header bilgisinin content-type kısmı application/json olması gerekirken text/html yazacaktır.

screenshot_8

 

Bunun önüne geçmek için kendi MediaTypeFormatter ımız yazıp config ayarlarırında tanımlayacağız.

Öncelikle projemize MyJsonFormatter adında bir class ekledim :

kodlar:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Web;

namespace WebApiApp
{
    public class MyJsonFormatter : JsonMediaTypeFormatter
    {
        public MyJsonFormatter()
        {
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        }
        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
            headers.ContentType = new MediaTypeHeaderValue("application/json");
        }
    }
}

screenshot_9

oluşturduğumuz class a JsonMediaTypeFormatter sınıfını implement ettik , sonrasında constructor ımızda bi önceki örneğimizde yaptığımız gibi text/html content-type ına destek verdiğimizi tanımladık.

sonrasında JsonMediaTypeFormatter  a ait olan SetDefaultContentHeaders methodunu override ederek header content-type ını her zaman application/json olarak dönmesini sağladık.

bu işlemlerden sonra oluşturduğumuz MediaTypeFormat sınıfımız WebApiConfig.cs dosyamıza tanımlamamız kaldı.

config.Formatters.Add(new MyJsonFormatter());

şeklinde kodumuzu eklememiz yeterli olacaktır .

WebApiConfig.cs : 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Net.Http.Formatting;

namespace WebApiApp
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

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

               
            );

            config.Formatters.Add(new MyJsonFormatter());
        }
    }
}

Artık Accept : “text/html” olarak gelen requestler de json olarak sonucumuz döncek ve header content-type bilgisinde “application/json” olacaktır.

screenshot_10

 

Örnek: CSV Formater :

Apimizde response olarak csv formatın sonucu almak için örnek csv formater ve kullanımı :

CSVFormatter.cs

using Egitim_ContentNavigation.Entity;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using System.Web;

namespace WebApiApp
{
    public class CSVFormatter : MediaTypeFormatter
    {
        public CSVFormatter()
        {
            this.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/csv"));
        }
        public CSVFormatter(MediaTypeMapping mediaTypeMapping):this()
        {
            this.MediaTypeMappings.Add(mediaTypeMapping);
        }
        public override bool CanReadType(Type type)
        {
            return false;
        }

        public override bool CanWriteType(Type type)
        {
            //List mi ?
            return type.GetInterfaces().Any(x => x == typeof(IEnumerable));
        }

        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
            headers.Add("Content-Disposition", "attachment; filename=" + Guid.NewGuid().ToString() + ".csv");
        }

        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
        {
            myWriteStream(type, value, writeStream);
            var task = new TaskCompletionSource<int>();
            task.SetResult(0);
            return task.Task;
        }
        private void myWriteStream(Type type, object value, Stream stream)
        {

            Type itemType = type.GetGenericArguments()[0];

            StringWriter _stringWriter = new StringWriter();

            _stringWriter.WriteLine(
                string.Join<string>(
                    ",", itemType.GetProperties().Select(x => x.Name)
                )
            );

            foreach (var obj in (IEnumerable<object>)value)
            {

                var vals = obj.GetType().GetProperties().Select(
                    pi => new {
                        Value = pi.GetValue(obj, null)
                    }
                );

                string _valueLine = string.Empty;

                foreach (var val in vals)
                {
                    if (val.Value != null)
                    {
                        var _val = val.Value.ToString();

                        if (_val.Contains("\r"))
                            _val = _val.Replace("\r", " ");
                        if (_val.Contains("\n"))
                            _val = _val.Replace("\n", " ");

                        _valueLine = string.Concat(_valueLine, _val, ",");
                    }
                    else
                    {
                        _valueLine = string.Concat(_valueLine, string.Empty, ",");
                    }
                }

                _stringWriter.WriteLine(_valueLine.TrimEnd(','));
            }

            var streamWriter = new StreamWriter(stream);
            streamWriter.Write(_stringWriter.ToString());
            streamWriter.Close();
        }
    }
}

sonrasında formatter tanımlamasını yapmamız gerekce , WebApiConfgi.cs te yapabileceğimiz gibi Global.asax dosyasında da bu tanımlamayı yapabiliriz.

Global.asax  :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web;
using System.Web.Http;
using System.Web.Routing;

namespace Egitim_ContentNavigation
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);
            GlobalConfiguration.Configuration.Formatters.Add(new CSVFormatter(new QueryStringMapping("format", "csv","text/csv")));
            //url?format=csv
        }
    }
}

kullanımı : wepapi url parametre olarak format=csv yazdığımızda dönen sonuç eğer IEnumerable ise csv formatında sonuç verecektir. (IEnumerable kontrolü CSVFormatter.cs dosyasında CanWriteType metodunda yapılmıştır. )

Bu şekilde csv formatında response alınabilir.

 

Print Friendly, PDF & Email

You may also like...

Bir cevap yazın