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

前端 未结 6 2065
时光取名叫无心
时光取名叫无心 2020-12-04 17:34

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

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

相关标签:
6条回答
  • 2020-12-04 18:09

    Very late to this party with a grossly simplified solution. I had success with this code in the controller method:

           public HttpResponseMessage FileHandler()
           {
            HttpResponseMessage response = new HttpResponseMessage();
    
            using (var reader = new StreamReader(System.Web.HttpContext.Current.Request.GetBufferedInputStream()))
            {
                string plainText = reader.ReadToEnd();
            } .....}
    

    And on the client side, these are the Ajax options I used:

    var ajaxOptions = {
    url: 'api/fileupload/' + "?" + $.param({ "key": metaKey2, "File-Operation": "Remove", "removalFilePath": $removalFilePath, "Audit-Model": model, "Parent-Id": $parentId, "Audit-Id": $auditId }),
    type: 'POST', processData: false, contentType: false, data: "BOB"
    };

    0 讨论(0)
  • 2020-12-04 18:16

    In ASP.NET Core 2.0 you simply do the following :-

    using (var reader = new StreamReader(Request.Body))
    {
          string plainText= reader.ReadToEnd();
    
          // Do something else
    
          return Ok(plainText);
    }
    
    0 讨论(0)
  • 2020-12-04 18:23

    In some situations it might be simpler to let the JsonMediaTypeFormatter let do the work:

    var formatter = GlobalConfiguration.Configuration.Formatters.Where(f=>f is System.Net.Http.Formatting.JsonMediaTypeFormatter).FirstOrDefault();
    if (!formatter.SupportedMediaTypes.Any( mt => mt.MediaType == "text/plain" ))
        formatter.SupportedMediaTypes.Add( new MediaTypeHeaderValue( "text/plain" ) );
    
    0 讨论(0)
  • 2020-12-04 18:24

    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.

    0 讨论(0)
  • 2020-12-04 18:24

    Purified version using of gwenzek's formatter employing async/await:

    public class PlainTextFormatter : MediaTypeFormatter
    {
        public PlainTextFormatter()
        {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
        }
    
        public override bool CanReadType(Type type) =>
            type == typeof(string);
    
        public override bool CanWriteType(Type type) =>
            type == typeof(string);
    
        public override async Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            var streamReader = new StreamReader(readStream);
            return await streamReader.ReadToEndAsync();
        }
    
        public override async Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)
        {
            var streamReader = new StreamWriter(writeStream);
            await streamReader.WriteAsync((string) value);
        }
    }
    

    Please note I intentionally do not dispose StreamReader/StreamWriter, as this will dispose underlying streams and break Web Api flow.

    To make use of it, register while building HttpConfiguration:

    protected HttpConfiguration CreateHttpConfiguration()
    {
        HttpConfiguration httpConfiguration = new HttpConfiguration();
        ...
        httpConfiguration.Formatters.Add(new PlainTextFormatter());
        ...
        return httpConfiguration;
    }
    
    0 讨论(0)
  • 2020-12-04 18:26

    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());
    
    0 讨论(0)
提交回复
热议问题