Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to post plain text to ASP.NET Web API endpoint?

I have an ASP.NET Web API endpoint with controller action defined as follows :

[HttpPost] public HttpResponseMessage Post([FromBody] object text) 

If my post request body contains plain text ( i.e. should not be interpreted as json, xml, or any other special format ), then I thought I could just include following header to my request :

Content-Type: text/plain 

However, I receive error :

No MediaTypeFormatter is available to read an object of type 'Object' from content with media type 'text/plain'. 

If I change my controller action method signature to :

[HttpPost] public HttpResponseMessage Post([FromBody] string text) 

I get a slightly different error message :

No MediaTypeFormatter is available to read an object of type 'String' from content with media type 'text/plain'.

like image 786
BaltoStar Avatar asked Sep 02 '14 20:09

BaltoStar


2 Answers

Actually it's a shame that web API doesn't have a MediaTypeFormatter for plain text. Here is the one I implemented. It can also be used to Post content.

public class TextMediaTypeFormatter : MediaTypeFormatter {     public TextMediaTypeFormatter()     {         SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));     }      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 Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, System.Net.TransportContext transportContext, System.Threading.CancellationToken cancellationToken)     {         var buff = System.Text.Encoding.UTF8.GetBytes(value.ToString());         return writeStream.WriteAsync(buff, 0, buff.Length, cancellationToken);     }      public override bool CanReadType(Type type)     {         return type == typeof(string);     }      public override bool CanWriteType(Type type)     {         return type == typeof(string);     } } 

You need to "register" this formatter in your HttpConfig by something like that:

config.Formatters.Insert(0, new TextMediaTypeFormatter()); 
like image 192
gwenzek Avatar answered Sep 29 '22 18:09

gwenzek


Since Web API doesn't have out of box formatter for handling text/plain, some options:

  1. Modify your action to have no parameters... reason is having parameters triggers request body de-serialization. Now you can read the request content explicitly by doing await Request.Content.ReadAsStringAsync() to get the string

  2. Write a custom MediaTypeFormatter to handle 'text/plain'... it's actually simple to write in this case and you could keep the parameters on the action.

like image 32
Kiran Avatar answered Sep 29 '22 18:09

Kiran