核心2.1:尝试读取HttpRequest.Body时为空

8

我正在尝试从HttpRequest.Body中读取流数据,但是我得到了一个空字符串。 这个请求是从.net项目发送的。

        HttpWebRequest request = null;
        Uri uri = new Uri(**Endpoint**);
        UTF8Encoding encoding = new UTF8Encoding();
        byte[] bytes = encoding.GetBytes(message);
        request = (HttpWebRequest)WebRequest.Create(uri);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = bytes.Length;
        request.UseDefaultCredentials = true;
        using (Stream writeStream = request.GetRequestStream()) {
            writeStream.Write(bytes, 0, bytes.Length);
        }
        try {
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode == HttpStatusCode.OK) {
                return true;
            } else {
                return false;
            }
        } catch {
            lock (endpointLock) {
                _pushHttpEndpoint = null;
            }
            return false;
        }

请求被发送到这里。这是一个.NET Core 2.1应用程序。我试图读取请求体中的数据,但返回为空。

    [HttpPost]
    public string Post()
    {
        var bodyStr = "";
        var req = HttpContext.Request;           
        req.EnableRewind();            
        using (StreamReader reader
                  = new StreamReader(req.Body, Encoding.UTF8, true, 1024, true))
        {
            bodyStr = reader.ReadToEnd();
        }    

        req.Body.Seek(0, SeekOrigin.Begin);
        //do other stuff
        return bodyStr;
     }

请问有人能帮我解决这个问题吗? 我们现在的情况是无法更改 .net 解决方案代码。所有更改都应在 .net core 解决方案方面进行。我们正在努力将新的 API 安置在现有端点的位置 :(


检查我的答案。我刚刚在.Net Core 2.2中完成了同样的事情。这可能适用于你。 - Jonathan Alfaro
3个回答

4

首先我知道这个问题是关于ASP.NET Core 2.1的,但我在2.2上也遇到了同样的问题。

以下是我的解决方法:

在ASP.NET Core 2.2中启用此功能的方法如下:

首先,在Startup.cs类中启用请求管道级别的缓冲。

  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {

    // Configure the HTTP request pipeline.
    app.Use(async (context, next) =>
    {
      //enable buffering of the request

      context.Request.EnableBuffering();

      await next();

    });
  }

在你的操作中的第二步:

  Request.EnableRewind();
  Request.Body.Seek(0, SeekOrigin.Begin);

  using (var reader = new StreamReader(Request.Body, Encoding.ASCII))
  {
    var requestBody = reader.ReadToEnd();
    // Reset the stream just in case it is needed further down the execution pipeline       
    Request.Body.Seek(0, SeekOrigin.Begin);
  }

也没有帮助。 - Naruto
@Naruto,它怎么没有帮助到你?我已经在生产环境中使用了这段代码……那么它为什么对你不起作用呢? - Jonathan Alfaro
1
尝试了很多方法,但这个方法帮了我。:-) 谢谢分享。 - Dharmesh Tailor
1
我刚在.NET Core 3.1中测试了这个。效果如广告所述。 - Jonathan Allen

1

您的类型为“type is application/x-www-form-urlencoded”,因此请使用[FromForm]属性。下面的代码仅供参考:

.Net项目:

        HttpWebRequest request = null;
        Uri uri = new Uri("https://localhost:44365/Home/Post");
        UTF8Encoding encoding = new UTF8Encoding();
        var postData = "thing1=hello";
        postData += "&thing2=world";
        byte[] bytes = encoding.GetBytes(postData);
        request = (HttpWebRequest)WebRequest.Create(uri);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = bytes.Length;
        request.UseDefaultCredentials = true;
        using (Stream writeStream = request.GetRequestStream())
        {
            writeStream.Write(bytes, 0, bytes.Length);
        }
        try
        {
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode == HttpStatusCode.OK)
            {
                //return true;
            }
            else
            {
               // return false;
            }
        }
        catch(Exception e)
        {

        }

在你的 .net Core 项目中:
    [HttpPost]
    public string Post([FromForm]AcceptValue acceptValue)
    {

        //do other stuff
        return "";
    }

    public class AcceptValue {
        public string thing1 { get; set; }

        public string thing2 { get; set; }
    }

Result :


2
实际上我们正在尝试破解我们的代码。问题是数据不能以这种方式发送。 var postData = "thing1=hello"; postData += "&thing2=world"; .Net代码是旧的,我们处于无法更改的情况。发送的数据可以是任何格式,我们需要在.NET Core解决方案中处理。任何更改都应在.NET Core解决方案端完成。我们处于棘手的位置。 :( - Phoebe Buffay
请检查我的答案。我刚刚在ASP.NET Core 2.2中完成了这个。我不确定它是否适用于ASP.NET Core 2.1。但我知道它适用于2.2。 - Jonathan Alfaro

-3

你应该使用 [FromBody] 属性。

它将是这样的:

[HttpPost]
public string Post([FromBody] object body) {
// do stuff here
}

1
这并没有帮助。在 .net core 中,对于“application/x-www-form-urlencoded”请求,使用 [FromBody] 会导致 415 不支持的媒体类型错误。 - Phoebe Buffay
@Amrutha ,FromBody 用于 json 类型,如果类型为 application/x-www-form-urlencoded,则应使用 FromForm。请查看我的回复。 - Nan Yu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接