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

Jyi*_*ina 5 asp.net-core-mvc asp.net-core

如何在asp.net core MVC控制器中使用ReadAsStringAsync?Microsoft.AspNetCore.Mvc.Request 没有 Content 属性。有替代方案吗?谢谢你!

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

        ////

    }
}
Run Code Online (Sandbox Code Playgroud)

Tao*_*hou 6

对于 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用:

public async Task<string> ReadStringDataManual()
{
    return await Request.GetRawBodyStringAsync();
}
Run Code Online (Sandbox Code Playgroud)

参考:在 ASP.NET Core API 控制器中接受原始请求正文内容


Dav*_*ang 0

您希望可以.ReadAsStringAsync()在当前的 MVC 请求上使用,因为也许您已经见过这样的东西?

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

HttpClient这是您在应用程序中获取外部数据/资源的方式。.ReadAsStringAsync()位于 a 之外,这是orHttpContent的属性。和都在命名空间中。HttpRequestMessageHttpResponseMessageHttpRequestMessageHttpResponseMessageSystem.Net.Http

但现在您就在应用程序本身中了!事情的运作方式有点不同。我们还没有对该请求的回复(因为我们还没有回复return View();)。因此我假设您想查看的内容是传入的请求的内容?

GET请求的内容

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

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

    return View();
}
Run Code Online (Sandbox Code Playgroud)

POST请求的内容

POST请求传入时,Request.Body可能并不总是有您正在查找的数据。这取决于POST请求的内容类型。

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

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

    Request.Body    // will be empty!

    ...
}
Run Code Online (Sandbox Code Playgroud)

如果您在不指定的情况下jQuery触发POSTcontentType请求,则默认为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>
}
Run Code Online (Sandbox Code Playgroud)
[HttpPost]
public async Task<IActionResult> Test()
{
    string body;
    using (var reader = new StreamReader(Request.Body))
    {
        body = await reader.ReadToEndAsync();
    }

    return Json(body);
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

结论

如果您想HttpClient在 MVC 应用程序中调用外部服务,您可以使用IHttpClientFactory, HttpClientfromSystem.Net.Http并从请求或响应中获取 a HttpContent,而不会有太多麻烦。然后你就可以把ReadAsStringAsync()它关掉了。

如果您想查看从客户端发送到 MVC 应用程序的请求数据,MVC 已经做了很多工作来帮助您使用模型绑定来绑定数据。您还可以使用. StreamReader请注意,这取决于内容类型,Request.Body可能不会有您所期望的。