Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

How to use ReadAsStringAsync in asp.net core MVC controller? The Microsoft.AspNetCore.Mvc.Request does not have Content property. Is there an alternative to this? Thank you!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using AuthLibrary;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web;
using System.Web.Http;
using System.Threading.Tasks;
[Microsoft.AspNetCore.Mvc.Route("TestAPI")]
public class TestController : Controller
    [Microsoft.AspNetCore.Mvc.HttpPost]
    [AllowAnonymous]
    [Microsoft.AspNetCore.Mvc.Route("Start")]
      public async Task<HttpResponseMessage> Start()
        string req = await this.Request.Content.ReadAsStringAsync();
                Have you tried await?  Not sure from your post WHEN you're seeing the content not available, but since it's async, it wouldn't necessarily be at the time you're throwing an exception.  Here's an existing accepted answer Stack Overflow Question with sample code
– markaaronky
                May 9, 2019 at 18:39
                Please see my updated code. I tried await too. I meant to say "Content" property is not available. I see only ContentType and ContentLength.
– Jyina
                May 9, 2019 at 18:56

For Asp.Net Core MVC, you could access the request content with request.Body.

Here is an extension:

public static class HttpRequestExtensions
    /// <summary>
    /// Retrieve the raw body as a string from the Request.Body stream
    /// </summary>
    /// <param name="request">Request instance to apply to</param>
    /// <param name="encoding">Optional - Encoding, defaults to UTF8</param>
    /// <returns></returns>
    public static async Task<string> GetRawBodyStringAsync(this HttpRequest request, Encoding encoding = null)
        if (encoding == null)
            encoding = Encoding.UTF8;
        using (StreamReader reader = new StreamReader(request.Body, encoding))
            return await reader.ReadToEndAsync();
    /// <summary>
    /// Retrieves the raw body as a byte array from the Request.Body stream
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    public static async Task<byte[]> GetRawBodyBytesAsync(this HttpRequest request)
        using (var ms = new MemoryStream(2048))
            await request.Body.CopyToAsync(ms);
            return ms.ToArray();
public async Task<string> ReadStringDataManual()
    return await Request.GetRawBodyStringAsync();

Reference:Accepting Raw Request Body Content in ASP.NET Core API Controllers

You hope you can use .ReadAsStringAsync() on the current MVC request because perhaps you've seen something like this?

using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Threading.Tasks;
namespace DL.SO.UI.Web.Controllers
    public class DashboardController : Controller
        // In order to be able to inject the factory, you need to register in Startup.cs
        // services.AddHttpClient()
        //     .AddRouting(...)
        //     .AddMvc(...);
        private readonly IHttpClientFactory _httpClientFactory;
        public DashboardController(IHttpClientFactory httpClientFactory)
            _httpClientFactory = httpClientFactory;
        public async Task<IActionResult> Index()
            var client = _httpClientFactory.CreateClient();
            var request = new HttpRequestMessage(HttpMethod.Get, "https://www.google.com");
            var response = await client.SendAsync(request);
            if (response.IsSuccessStatusCode)
                string bodyContent = await response.Content.ReadAsStringAsync();
            return View();

This is how you use HttpClient to fetch external data/resources in an app. .ReadAsStringAsync() is off an HttpContent, which is the property of either HttpRequestMessage or HttpResponseMessage. Both HttpRequestMessage and HttpResponseMessage are in System.Net.Http namespace.

But now you're in the app itself! Things work a little bit differently. We don't have a response for the request yet (because we haven't done return View();). Hence I assume the content you want to look at is the content of the request coming in?

GET request's content

When a GET request comes in, MVC will automatically bind request's query strings to action method parameters in the controller. They're also available in the Query property off the current Request object:

public IActionResult Index(int page = 1, int size = 15)
    foreach (var param in Request.Query)
    return View();

POST request's content

When a POST request comes in, Request.Body might not always have the data you're looking for. It depends on the content type of the POST request.

By default when you're submitting a form, the content type of the request is form-data. MVC then will bind the inputs to your view model as the action parameter:

[HttpPost]
public async Task<IActionResult> Close(CloseReservationViewModel model)
    Request.Form    // contains all the inputs, name/value pairs
    Request.Body    // will be empty!

If you use jQuery to fire POST requests without specifying the contentType, it defaults to x-www-form-urlencoded:

@section scripts {
    <script type="text/javascript">
        $(function() {
            $.ajax({
                url: '@Url.Action("test", "dashboard", new { area = "" })',
                data: {
                    name: 'David Liang',
                    location: 'Portland Oregon'
                method: 'POST'
            }).done(function (response) {
                console.info(response);
    </script>
[HttpPost]
public async Task<IActionResult> Test()
    string body;
    using (var reader = new StreamReader(Request.Body))
        body = await reader.ReadToEndAsync();
    return Json(body);

Conclusion

If you want to use HttpClient to call external services inside your MVC app, you can utilize IHttpClientFactory, HttpClient from System.Net.Http and get a HttpContent from either the request or response without too much trouble. Then you can do ReadAsStringAsync() off it.

If you want to peek on the request data sent from the client to your MVC app, MVC has already done so much to help you bind the data using model binding. You can also read request's body for POST requests with a StreamReader. Just pay attention that depends on the content type, Request.Body might not have what you expect.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.