Core 2.1 HttpRequest.Body 尝试读取时为空

Posted

技术标签:

【中文标题】Core 2.1 HttpRequest.Body 尝试读取时为空【英文标题】:Core 2.1 HttpRequest.Body is empty when trying to read it 【发布时间】:2019-04-22 14:18:59 【问题描述】:

我正在尝试从 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 核心解决方案方面进行。我们正在尝试用新的 api 代替现有的 Endpoint。 :(

【问题讨论】:

检查我的答案。我只是在 .Net Core 2.2 中做了同样的事情。它可能对你有用。 【参考方案1】:

首先我知道问题是关于 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 怎么没有帮助?我有这个代码在生产中......那么它怎么不适合你呢? 尝试了很多东西,但这个帮助了我。 :-) 感谢分享。 我刚刚在 .NET Core 3.1 中对此进行了测试。像宣传的那样工作。【参考方案2】:

你的类型是 "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 核心项目上:

    [HttpPost]
    public string Post([FromForm]AcceptValue acceptValue)
    

        //do other stuff
        return "";
    

    public class AcceptValue 
        public string thing1  get; set; 

        public string thing2  get; set; 
    

【讨论】:

实际上我们正在尝试破解我们的代码。问题是不能以这种方式发送数据。 var postData = "thing1=hello"; postData += "&thing2=世界"; .Net 代码是旧代码,我们处于不改变的情况。发送的数据可以是任何格式,我们在 .net 核心解决方案中需要它。任何更改都应在 .net 核心解决方案方面进行。我们处于棘手的位置。 :( 请检查我的回答。我只是在 ASP.NET Core 2.2 中做到了这一点。我不确定它是否适用于 ASP.NET Core 2.1。但我知道它适用于 2.2【参考方案3】:

您应该使用 [FromBody] 属性。

会是这样的:

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

【讨论】:

这没有帮助。 [FromBody] for "application/x-www-form-urlencoded" 请求在 .net core 中给出 415 unsupported media type error。 @Amrutha,FromBody 用于 json 类型,如果类型为 application/x-www-form-urlencoded 则应使用 FromForm 。查看我的回复

以上是关于Core 2.1 HttpRequest.Body 尝试读取时为空的主要内容,如果未能解决你的问题,请参考以下文章

Django--view.py详解

django response reuqest

Django中的request对象详解

HttpReponse

HttpContext 上的管道

django 获取request请求对象及response响应对象中的各种属性值