【问题标题】:Asp Net Core Web Api POST Request.Body always length 0Asp Net Core Web Api POST Request.Body 总是长度为 0
【发布时间】:2019-05-20 11:52:37
【问题描述】:

我正在开发一项服务,该服务将使用 HTTP Content-Type: application/octet-stream 和 Transfer-Encoding: chunked 接收文件。

我能够让服务器获取请求DisableFormValueModelBindingRequestSizeLimit

但是当我从 Request.Body 中获取数据时,长度始终为 0。

在框架中我会使用类似的东西 request.Content.ReadAsStreamAsync(); 但这似乎不是 Core 的选项。

我应该如何获取来自客户端(邮递员)的流内容?

使用 Postman,我尝试了 body 的 binary 和 form-data 选项,但是一旦它到达服务器,都没有最终拥有 body。通读一些文档,有关于创建使用 MultipartReader 的新格式化程序的建议。但这一切看起来都是基于我没有使用的 multipart/form-data 内容类型。我也尝试使用 curl 发送请求,但结果是一样的。

程序.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>();
}

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

控制器

[HttpPost]
[RequestSizeLimit(2147483648)] // https://stackoverflow.com/questions/43305220/form-key-or-value-length-limit-2048-exceeded
[DisableFormValueModelBinding] // https://dotnetcoretutorials.com/2017/03/12/uploading-files-asp-net-core/
public void Upload()
{
    Request.EnableRewind();
    Stream body = Request.Body;
    Debug.WriteLine(body.Length);
}

【问题讨论】:

  • 您是否在 Postman 中指定了“Body”?
  • @GabrielLuci 我做到了。我尝试了二进制和表单数据选项,但最终都没有实体。通读一些文档,有关于创建使用 MultipartReader 的新格式化程序的建议。但这一切看起来都是基于我没有使用的 multipart/form-data 内容类型。
  • @GabrielLuci 除非我错过阅读文档,否则 StreamFile 是他们创建的用于处理多部分数据的辅助方法。除非我误解了 MultipartReader 支持的内容,否则这不适用于我的情况。
  • 对。这就说得通了。但我想我明白为什么它是 0。看看我的答案。

标签: c# .net-core asp.net-core-webapi


【解决方案1】:

我读到 article 是从那里获得 [DisableFormValueModelBinding] 的。该属性的全部意义在于阻止 ASP.NET 读取正文。所以body.Length 为 0 是有道理的。它只是还没有被阅读(而且在你阅读整个内容之前你无法知道长度)。

但是你可以读取请求的Content-Length标头:

var length = Request.ContentLength;

【讨论】:

  • 我不同意。该属性阻止其他格式化程序读取正文。理想情况下,如果尸体被单独留下,它应该可以访问。也许如果我制作一个自定义格式化程序,我将可以访问它?
  • 我并不是说它会阻止 阅读它。我是说你还没有读过它。流的全部意义在于,您可以处理传入的内容,而无需将整个内容加载到内存中。所以根据它的定义,在你读到最后之前你不知道有多少数据,你还没有读完——或者除非有别的东西告诉你:这就是 Content-Length 标题为了。客户端在该标头中告诉您,“这是我要发送的数据量”。
  • 好吧,即使长度和位置为 0,我也应该能够对 Body 进行读取?我可以试一试。虽然长度应该返回流中有多少字节。
  • 根据初步测试,您是正确的。尽管长度为 0,但我能够从流中读取一个字节。当我将文件传递并返回到其原始形式时,我将更新。
  • 那么如果流中有数据,为什么没有长度?我的想法是,在收到整个文件之前,长度只会增加。并且流将管理不在内存中的数据的去向。例如 FileStreams 长度就是文件的长度。
猜你喜欢
  • 1970-01-01
  • 2018-07-26
  • 2018-01-24
  • 1970-01-01
  • 2019-06-29
  • 1970-01-01
  • 2017-08-28
  • 2021-09-14
  • 2019-01-24
相关资源
最近更新 更多