首页 > 解决方案 > WebApiCompatShim 无法在 .net 核心中正确处理 ByteRangeStreamContent

问题描述

我们必须根据请求中的指定发送部分文件HttpRange。在 .Net 核心中,我们可以返回任何继承自的对象,FileResult并且此类具有用于指定是否必须启用范围处理的属性:

/// <summary>
/// Gets or sets the value that enables range processing for the <see cref="FileResult"/>.
/// </summary>
public bool EnableRangeProcessing { get; set; }

我们可以返回这些对象,框架将自动处理请求的“http range”值。到目前为止好多了。但是,他们有意识地决定在一个请求中不支持多个字节范围,在这种情况下,整个文件内容将作为响应发送。(这里是我关于这个问题的 SO 问题的链接)

在我们的案例中,客户希望在一个请求中发送多个字节范围。

出于这个原因,我有两个选择。要么创建支持单个和多个范围的新动作结果类型。或者使用Microsoft.AspNetCore.Mvc.WebApiCompatShim由 Microsoft 开发并在 ASP.NET Core MVC 中与 ASP.NET Web API 2 兼容的包,以简化现有 Web API 实现的迁移。

我已经创建了一些自定义类型来支持多个范围,但必须对其进行重构和测试。这就是为什么我认为第二种方法可能与这种情况更相关。

所以,这里有步骤。首先,我安装了那个包。然后添加了对AddWebApiConventions. 这将HttpResponseMessageOutputFormatter帮助并提示Json序列化程序正确地执行序列化魔术。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddWebApiConventions();
}

然后刚刚创建了 new ApiController,它基于以下内容创建响应ByteRangeStreamContent

public class FileController : ApiController
{
    [HttpGet]
    [HttpHead]
    [Route("download")]
    public ResponseMessageResult Download(string filePath)
    {
        var response = Request.CreateResponse(HttpStatusCode.PartialContent);

        var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
        response.Content = new ByteRangeStreamContent(fileStream, Request.Headers.Range, MediaTypeNames.Application.Octet);

        return ResponseMessage(response);
    }
}

该端点可以在 .Net 中执行单个和多个 http 范围请求。但是,在 .net 核心中,它再次仅支持单字节范围响应。

假设我有这样内容的文件:

ABCDFGHIJKLMNOPQRSYUVWXYZ

在单字节范围请求的情况下,响应为:

curl -H  Range:bytes=1-5  http://localhost:55348/File/download?filePath=D:\Request.txt -i
ABCDF

但是,如果有多个字节范围请求,它会奇怪地返回第一个范围的完整内容:

curl -H  Range:bytes=1-5,6-8  http://localhost:55348/File/download?filePath=D:\Request.txt -i

--51239b4a-9749-481f-a353-6cad668fb7dc
Content-Type: application/octet-stream
Content-Range: bytes 1-5/25

ABCDFGHIJKLMNOPQRSYUVWXYZ     -- As you see full content is returned instead of `ABCDF`
--51239b4a-9749-481f-a353-6cad668fb7dc
Content-Type: application/octet-stream
Content-Range: bytes 6-8/25

无法理解为什么它不能在 .net Core 中适当地创建响应。

标签: c#asp.net-corecurlasp.net-web-api.net-core

解决方案


推荐阅读