My Adventures in Coding

June 19, 2012

C# – Supporting text/plain in an MVC 4 Web API application

Filed under: .NET,c#,MVC — Brian @ 10:50 pm
Tags: , , , , , ,

If you have just created a brand new MVC 4 Web API application and when posting data with content-type: text/plain to a method in your ApiController that takes a string, you notice that the value in the string is null, this is caused by your application not having support for the media type “text/plain”.

No worries, after some digging I figured out how to get this to work.

Create the following custom MediaTypeFormatter in your application

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

namespace WebApiMvc4Example
{
    public class TextMediaTypeFormatter : MediaTypeFormatter
    {
        public TextMediaTypeFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));
        }

        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            var taskCompletionSource = new TaskCompletionSource<object>();
            try
            {
                var memoryStream = new MemoryStream();
                readStream.CopyTo(memoryStream);
                var s = System.Text.Encoding.UTF8.GetString(memoryStream.ToArray());
                taskCompletionSource.SetResult(s);
            }
            catch (Exception e)
            {
                taskCompletionSource.SetException(e);
            }
            return taskCompletionSource.Task;
        }

        public override bool CanReadType(Type type)
        {
            return type == typeof(string);
        }

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

Add the custom MediaTypeFormatter into the Application_Start method in your Global.asax.cs file

using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace WebApiMvc4Example
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            // Add a reference here to the new MediaTypeFormatter that adds text/plain support
            GlobalConfiguration.Configuration.Formatters.Insert(0, new TextMediaTypeFormatter());
        }
    }
}

Now add the “FromBody” tag to your POST method that takes in a string in your ApiController

using System;
using System.Collections.Generic;
using System.IO;
using System.Web.Http;

namespace WebApiMvc4Example.Controllers
{
    public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        // Add the "FromBody" tag
        public void Post([FromBody] string value)
        {
            System.Diagnostics.Debug.WriteLine("******Woohoo: " + value);
        }

        // PUT api/values
        public void Put(string value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }
    }
}

That is all. So now if you start up your application:
POST to http://localhost:MYPORT/api/values with headers “content-type: text/plain” and with body “SOMETEXT” it will work just fine now.

I hope this helps!

Advertisements

Create a free website or blog at WordPress.com.