如何在asp.net核心MVC控制器中使用ReadAsStringAsync?

时间:2019-05-09 18:34:06

标签: asp.net-core asp.net-core-mvc

如何在asp.net核心MVC控制器中使用ReadAsStringAsync? Microsoft.AspNetCore.Mvc.Request没有内容属性。是否有替代方法?谢谢!

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();

        ////

    }
}

2 个答案:

答案 0 :(得分:0)

您希望您可以在当前的MVC请求上使用.ReadAsStringAsync(),因为也许您已经看到了类似的内容?

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();
        }
    }
}

这是您使用HttpClient来获取应用程序中的外部数据/资源的方式。 .ReadAsStringAsync()关闭了HttpContentHttpRequestMessage的属性HttpResponseMessageHttpRequestMessageHttpResponseMessage都位于System.Net.Http命名空间中。

但是现在您已经在应用程序中了!事情有些不同。我们尚未收到请求的回复(因为我们尚未完成return View();)。因此,我假设您要查看的内容是请求的内容?

获取请求的内容

收到 GET 请求时,MVC会自动将请求的查询字符串绑定到控制器中的操作方法参数。也可以在当前Query对象的Request属性中使用它们:

public IActionResult Index(int page = 1, int size = 15)
{
    foreach (var param in Request.Query)
    {
        ...
    }

    return View();
}

POST请求的内容

收到 POST 请求时,Request.Body可能并不总是具有您要查找的数据。这取决于 POST 请求的内容类型。

默认情况下,当您提交表单时,请求的内容类型为表单数据。然后,MVC将输入作为操作参数绑定到您的视图模型:

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

    Request.Body    // will be empty!

    ...
}

如果您使用jQuery触发 POST 请求而未指定contentType,则默认为 x-www-form-urlencoded :< / p>

@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);
}

enter image description here

结论

如果您想使用HttpClient来调用MVC应用程序中的外部服务,则可以利用IHttpClientFactory中的HttpClientSystem.Net.Http并获得一个HttpContent从请求或响应中获取,不会有太多麻烦。然后您可以关闭它ReadAsStringAsync()

如果您想窥探从客户端发送到MVC应用程序的请求数据,则MVC已经做了很多工作来帮助您使用模型绑定来绑定数据。您还可以使用StreamReader来读取 POST 请求的请求正文。只需注意取决于内容类型,Request.Body可能达不到您的期望。

答案 1 :(得分:0)

对于Asp.Net Core MVC,您可以使用request.Body访问请求内容。

以下是扩展名:

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();
}

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